Ruby에서 해당 클래스의 인스턴스 중 하나에서 클래스 메소드를 어떻게 호출합니까? 내가 가지고 있다고
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라인 Truck.default_make은 기본값을 검색합니다. 그러나 언급하지 않고 이것을 말하는 방법이 Truck있습니까? 있어야 할 것 같습니다.
답변
인스턴스 메서드 내에서 클래스의 리터럴 이름을 참조하는 대신을 호출하면 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출력 :
수업 방법 : 푸 인스턴스 방법 : Foo
답변
사용 self.class.blah은 ClassName.blah상속 과 관련하여 사용하는 것과 다릅니다 .
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" 답변
인스턴스 메소드 내부의 클래스 메소드에 액세스하려면 다음을 수행하십시오.
self.class.default_make문제에 대한 대체 솔루션은 다음과 같습니다.
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이제 우리 수업을 사용하자 :
t = Truck.new("Honda", 2000)
t.make
# => "Honda"
t.year
# => "2000"
t = Truck.new
t.make
# => "Toyota"
t.year
# => nil답변
delegate 메소드에 액세스 할 수있는 경우 다음을 수행 할 수 있습니다.
[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"또는 클래스 또는 인스턴스에 위임하려는 메소드가 두 개 이상인 경우 더 깨끗할 수 있습니다.
[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"주의 사항 :
delegate이상한 이름 충돌 문제가 발생하기 때문에 상태를 클래스 및 인스턴스로 변경하지 않는 모든 것을 무작위로하지 마십시오 . 이 작업은 드물게 수행하고 다른 사항을 확인한 후에 만 처리하십시오.
답변
self.class.default_make답변
당신은 올바른 방법으로하고 있습니다. 클래스 메소드 (C ++ 또는 Java의 ‘정적’메소드와 유사)는 인스턴스의 일부가 아니므로 직접 참조해야합니다.
참고로, 귀하의 예에서 ‘default_make’를 일반적인 방법으로 만드는 것이 더 좋습니다.
#!/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()클래스 메소드는 클래스를 사용하는 유틸리티 유형 함수에 더 유용합니다. 예를 들면 다음과 같습니다.
#!/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답변
하나 더:
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