2013-10-24 26 views
0

雖然開始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) 

和從未我諮詢the documentation

所以我現在的理解是見過method

如果你想從類中偷取一個方法,並將它製作成proclambda?),您將method粘貼在您希望的類方法的名稱之前,然後用引號括起來或寫爲符號。

這是想想它的正確方法嗎?或者它至少是Object#method的主要用途?

+0

lambda只是一種特殊的proc('lambda {} .class#=> Proc')。 –

回答

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] 
+0

謝謝先生。這會讓我接下來的幾個練習。 – dwilbank

+0

@dwilbank腳註:'&method'將方法轉換爲阻止 – texasbruce

0

本質上是肯定的。 method方法可讓您將其接收器的方法「打包」到類別Method的單個對象中。接收器是您稱爲.method的對象。 A對象也被稱爲「綁定」方法,因爲它綁定(附加)到接收器。

例子:

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) 

我們只能這樣做,因爲jal1Carjal1.is_a?(Car)true

我不使用上述在實際應用中建議,因爲它使代碼非常難以管理 - 但有時它有助於排除故障。