Ruby: Calling class method from instance

后端 未结 9 2037
谎友^
谎友^ 2021-01-29 17:26

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         


        
相关标签:
9条回答
  • 2021-01-29 17:59

    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
    
    0 讨论(0)
  • 2021-01-29 18:00

    If you have access to the delegate method you can do this:

    [20] pry(main)> class Foo
    [20] pry(main)*   def self.bar
    [20] pry(main)*     "foo bar"
    [20] pry(main)*   end  
    [20] pry(main)*   delegate :bar, to: 'self.class'
    [20] pry(main)* end  
    => [:bar]
    [21] pry(main)> Foo.new.bar
    => "foo bar"
    [22] pry(main)> Foo.bar
    => "foo bar"
    

    Alternatively, and probably cleaner if you have more then a method or two you want to delegate to class & instance:

    [1] pry(main)> class Foo
    [1] pry(main)*   module AvailableToClassAndInstance
    [1] pry(main)*     def bar
    [1] pry(main)*       "foo bar"
    [1] pry(main)*     end  
    [1] pry(main)*   end  
    [1] pry(main)*   include AvailableToClassAndInstance
    [1] pry(main)*   extend AvailableToClassAndInstance
    [1] pry(main)* end  
    => Foo
    [2] pry(main)> Foo.new.bar
    => "foo bar"
    [3] pry(main)> Foo.bar
    => "foo bar"
    

    A word of caution:

    Don't just randomly delegate everything that doesn't change state to class and instance because you'll start running into strange name clash issues. Do this sparingly and only after you checked nothing else is squashed.

    0 讨论(0)
  • 2021-01-29 18:05

    One more:

    class Truck
      def self.default_make
        "mac"
      end
    
      attr_reader :make
    
      private define_method :default_make, &method(:default_make)
    
      def initialize(make = default_make)
        @make = make
      end
    end
    
    puts Truck.new.make # => mac
    
    0 讨论(0)
  • 2021-01-29 18:11
    self.class.default_make
    
    0 讨论(0)
  • 2021-01-29 18:13

    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
    
    0 讨论(0)
  • 2021-01-29 18:16

    Similar your question, you could use:

    class Truck
      def default_make
        # Do something
      end
    
      def initialize
        super
        self.default_make
      end
    end
    
    0 讨论(0)
提交回复
热议问题