tags:

views:

78

answers:

4

In Ruby, how do you call a class method from one of that class's instances? Say I have

class Truck
  def self.default_make
    # Class method.
    "mac"
  end

  def initialize
    # Instance method.
    Truck.default_make  # gets the default via the class's method.
    # But: I wish to avoid mentioning Truck. Seems I'm repeating myself.
  end
end

the line Truck.default_make retrieves the default. But is there a way of saying this without mentioning Truck? It seems like there should be.

+1  A: 

You're doing it the right way. Class methods (similar to 'static' methods in C++ or Java) aren't part of the instance, so they have to be referenced directly.

On that note, in your example you'd be better served making 'default_make' a regular method:

#!/usr/bin/ruby

class Truck
    def default_make
        # Class method.
        "mac"
    end

    def initialize
        # Instance method.
        puts default_make  # gets the default via the class's method.
    end
end

myTruck = Truck.new()

Class methods are more useful for utility-type functions that use the class. For example:

#!/usr/bin/ruby

class Truck
    attr_accessor :make

    def default_make
        # Class method.
        "mac"
    end

    def self.buildTrucks(make, count)
        truckArray = []

        (1..count).each do
            truckArray << Truck.new(make)
        end

        return truckArray
    end

    def initialize(make = nil)
        if( make == nil )
            @make = default_make()
        else
            @make = make
        end
    end
end

myTrucks = Truck.buildTrucks("Yotota", 4)

myTrucks.each do |truck|
    puts truck.make
end
Maha
I disagree that `default_make` should be an instance method. Even if it's simpler for these examples, it's not the right semantics - the default is a product of the class, not objects that belong to the class.
Peter
+5  A: 

Rather than referring to the literal name of the class, inside an instance method you can just call self.class.whatever.

class Foo
    def self.some_class_method
        puts self
    end

    def some_instance_method
        self.class.some_class_method
    end
end

print "Class method: "
Foo.some_class_method

print "Instance method: "
Foo.new.some_instance_method

Outputs:

Class method: Foo
Instance method: Foo
Mark Rushakoff
+2  A: 

To access a class method inside a instance method, do the following:

self.class.default_make

Here is an alternative solution for your problem:

class Truck

  attr_accessor :make, :year

  def make
    @make || "Toyota"
  end

  def initialize(make=nil, year=nil)
    self.year, self.make = year, make
  end
end

Now let's use our class:

t = Truck.new("Honda", 2000)
t.make
# => "Honda"
t.year
# => "2000"

t = Truck.new
t.make
# => "Toyota"
t.year
# => nil
KandadaBoggu
A: 
self.class.default_make
Justice