在启动RubyMonk级别2时,我看到了这一点:
class Calculator
def add(a, b)
return a + b
end
end
addition_method = Calculator.new.method("add")
addition = addition_method.to_proc
puts addition.call(5, 6)
之前从未见过method
,我咨询了the documentation
所以我现在的理解是:
如果你想从一个类中窃取一个方法,并将它变成一个proc
(lambda
?),你可以在类方法的名称前面加上method
你想要的,然后用引号括起来或写成符号。
这是考虑它的正确方法吗?或者它至少是Object#method
的主要用途?
答案 0 :(得分:4)
我认为你有正确的想法。更一般地说,method
方法只是一种将Ruby方法表示为Method object的方法,由于对象很有用,因此可能有用。
该示例代码中存在一些无关紧要的内容。这是另一个例子:
def add(a)
a + a
end
m = method(:add) # => #<Method: Object#add>
m.call(4) # => 8
这是另一个有用的例子:
def good?(n)
n > 5
end
[1, 4, 9].select(&method(:good?)) # => [9]
答案 1 :(得分:0)
基本上是的。 method
方法允许您将方法和的接收器“打包”到类Method
的单个对象中。接收器是您调用.method
的对象。 Method
对象也称为“绑定”方法,因为它绑定(附加)到接收方。
示例:
class Car
attr_accessor :make, :model
def initialize(make, model)
@make, @model = make, model
end
def drive(speed)
puts "#{@make}-#{@model} drove with speed #{speed}"
end
end
创建一个实例:
car1 = Car.new('Toyota', 'Corolla')
抓住方法并调用它:
car1drive = car1.method(:drive)
# Outputs "Toyota-Corolla drove with speed 5"
car1drive.call(5)
请注意我们不必将其转换为proc
以便在其上使用call
。
接收者绑定
为了演示该方法如何仍然绑定到其接收器,我们修改了接收器。注意Method
如何依赖于它来自的对象。即创建Method
做不拍摄接收者状态的快照,但每次调用时都会查询接收者。
car1.model = 'Rav4'
# Outputs "Toyota-Rav4 drove with speed 5"
car1drive.call(5)
我们也可以检索接收器:
car1drive.receiver == car1 # true
用作块
可以使用&
(隐式调用to_proc
)来代替块。这非常有效,因为each
为块生成一个参数,而我们的car1drive
方法也只接受一个参数。
# Outputs:
# Toyota-Rav4 drove with speed 1
# Toyota-Rav4 drove with speed 2
# Toyota-Rav4 drove with speed 3
[1,2,3].each(&car1drive)
未绑定的方法
我们还可以获取未绑定的方法并将其绑定到另一个Car
。
unbind
返回全新的UnboundMethod
;它不会改变绑定方法。
# This gives us an UnboundMethod.
# It can't be called; it's like a disembodied spirit.
# This doesn't change car1drive at all.
unbound_drive = car1drive.unbind
car2 = Car.new('Chevy', 'Cruze')
car2drive = unbound_drive.bind(car2)
# Outputs "Chevy-Cruze drove with speed 5"
car2drive.call(5)
您也可以直接使用UnboundMethod
课程获得与上述相同的Car
:
unbound_drive = Car.instance_method(:drive)
调用已在子类中重写的超类方法
这是一个很好的技巧,可以调用重写方法。假设您有一个覆盖方法的子类:
class Jalopy < Car
def drive(speed)
puts "The ailing #{@make}-#{@model} drove with speed #{speed}"
end
end
jal1 = Jalopy.new('Toyota', 'Corolla')
# Outputs "The ailing Toyota-Corolla drove with speed 5"
jal1.drive(5)
# I don't like the overridden output, give me the original instead!
unbound_car_drive = Car.instance_method(:drive)
car_drive_on_jal1 = unbound_car_drive.bind(jal1)
# Outputs "Toyota-Corolla drove with speed 5"
car_drive_on_jal1.call(5)
我们只能执行此操作,因为jal1
是Car
(jal1.is_a?(Car)
是true
)
我不建议在实际应用程序中使用上述内容,因为它使代码很难管理 - 但有时它有助于排除故障。