2016-09-21 77 views
3
符號和實例方法有些問題

我正在努力學習的「學習紅寶石艱難的歷程」 我的問題是紅寶石......關於Ruby的

下面的代碼是從練習40:

cities = {'CA'=> 'San Francisco', 'MI'=> 'Detroit', 'FL'=> 'Jacksonville'} 

cities['NY'] = 'New York' 
cities['OR'] = 'Portland' 

def find_city(map, state) 
    if map.include? state 
    return map[state] 
    else 
    return 'Not found.' 
    end 
end 

cities[:find] = method(:find_city) 

while true 
    print 'State? (ENTER to quit) ' 
    state = gets.chomp 

    break if state.empty? 

    puts cities[:find].call(cities, state) 
end 

我玩過代碼,並最終了解它是如何工作的。 但我還是不明白兩件事:

第一...

在對代碼的中間, 它定義的變量

cities[:find] = method(:find_city) 

正如我所知道的現在, :(冒號)聲明一個符號。 我想知道在這種情況下將變量命名爲cities[:find] 而不是使用cities_find是否更好?

我不太清楚有什麼不同,或者對於大多數rubyist來說可讀性很強?

而第二個也是同一條線。

method(:find_city) 

我知道它允許我調用find_city方法。 但是,爲什麼我必須在find_city之前冒號? 這段代碼是否意味着解析我放入符號的參數?

回答

-2

所以它實際上定義的proc,使:findfind_city有點像鍵和值... ...大概

0

cities[:find] = method(:find_city)

這裏,cities是哈希和方法將由method(:find_city)返回的對象分配給作爲符號的散列鍵find

我認爲這取決於你和你正在編寫這個程序的上下文。

一個簡單的method_var = method(:find_city)也可以在這裏工作。


method(:find_city)

我知道這讓我打電話給find_city方法。但是,爲什麼我必須在find_city之前放置一個冒號?這段代碼是否意味着解析我放入符號的參數?

在這裏,你傳遞方法的名稱作爲參數,你必須要麼把它作爲一個symbolstring

0

在Ruby中,method方法創建一個方法對象。這允許您在代碼中傳遞它,稍後在Method對象上使用.call方法進行調用。 因爲調用method(my_method)會評估my_method並將結果傳遞給,您需要一種方法來告訴method方法使用哪種方法。這就是爲什麼你基本上是在方法名傳遞作爲象徵注入method方法:d

2

我不得不說,瞭解Ruby的困難的方法給了我們什麼,我們不應該做一個真的真的真的很好的例子。紅寶石專家不會在他/她的項目中輸入這樣的代碼。這段代碼令人困惑,不可讀,並且是元編程的濫用。

無論如何,我解剖你的代碼。

混亂的部分下面這一行開始:

cities[:find] = method(:find_city) 

讓我們來看看=的右側。它會調用一個名稱爲method的方法,如您所知,方法調用的返回值是方法find_city,更確切地說,是一個Method對象,它包含方法find_city及其範圍。然後將該方法存儲在散列cities中,其中以符號:find爲關鍵字。所以cities價值現已成爲

{ 
    'CA'=> 'San Francisco', 
    'MI'=> 'Detroit', 
    'FL'=> 'Jacksonville', 
    'NY' => 'New York', 
    'OR' => 'Portland', 
    :find => #<Method:main.find_city> 
} 

你可以看到最後的鍵值對,真是很奇怪,它不應該存在,因爲哈希cities應該只有存儲的狀態和他們的首都。哎呀!

然後這裏來這個甚至怪異的表達cities[:find].call(cities, state)。讓我們看看這是如何工作的。

cities[:find]只檢索從哈希Method對象(還記得它包裝有什麼方法?)

cities[:find].call(cities, state)調用它包裝的方法,這是find_city,在範圍內的Method對象包裝,這是頂級級別對象(又名main),Method#call返回返回中包裝的任何方法。所以這個表達只是find_city(cities, state),寫成了一個外星人的風格。

+0

'寫成外星人風格:D +1! –