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