Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Calling class method from instance

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.

like image 887
Peter Avatar asked Mar 27 '10 01:03

Peter


People also ask

Can you call a class method on an instance Ruby?

In Ruby, a method provides functionality to an Object. A class method provides functionality to a class itself, while an instance method provides functionality to one instance of a class. We cannot call an instance method on the class itself, and we cannot directly call a class method on an instance.

How do you find the class method in Ruby?

Class Methods are the methods that are defined inside the class, public class methods can be accessed with the help of objects. The method is marked as private by default, when a method is defined outside of the class definition. By default, methods are marked as public which is defined in the class definition.


3 Answers

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
like image 101
Mark Rushakoff Avatar answered Oct 17 '22 04:10

Mark Rushakoff


Using self.class.blah is NOT the same as using ClassName.blah when it comes to inheritance.

class Truck
  def self.default_make
    "mac"
  end

  def make1
    self.class.default_make
  end

  def make2
    Truck.default_make
  end
end


class BigTruck < Truck
  def self.default_make
    "bigmac"
  end
end

ruby-1.9.3-p0 :021 > b=BigTruck.new
 => #<BigTruck:0x0000000307f348> 
ruby-1.9.3-p0 :022 > b.make1
 => "bigmac" 
ruby-1.9.3-p0 :023 > b.make2
 => "mac" 
like image 37
Mark B Avatar answered Oct 17 '22 04:10

Mark B


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 self.default_make
    "Toyota"
  end

  def make
    @make || self.class.default_make
  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
like image 20
Harish Shetty Avatar answered Oct 17 '22 04:10

Harish Shetty