2014-02-17 120 views
2

我對Ruby中的某些三元表達感到非常困惑。ruby​​中的三重尷尬

我有這樣的表達:

puts respond_to? "greeting".to_sym ? "hello" : "bye" 
當然

,這不是我在我的應用程序正在做的,就是給你看。

的事情是,上述表達式返回

false 

當它應該返回和hello,如果該方法存在bye,如果它不正確的?

如果我改變的表達,

puts respond_to?("greeting".to_sym) ? "hello" : "bye" 

返回正確的事情,無論是「你好」,如果它存在,「再見」,否則。

這是怎麼發生的?有沒有關於紅寶石三元表達的東西,我不知道?

只是讓你知道我的應用程序正確的代碼是:

respond_to?(path.to_sym) ? self.send(path) : "#" 

這對於數據庫存儲的標題菜單返回正確的道路,如果它不存在,它會簡單地把一個「# 「以避免錯誤。

回答

3

如果你不具備的respond_to括號,評估發生這樣

"greeting".to_sym ? "hello" : "bye" #results in "hello" 

puts respond_to? "hello" #results in false 

三元表達式將先被評估沒有括號爲respond_to

2

我在你的榜樣跑ruby --dump parsetree(總一個很好的方法來查看真正發生的事情)。在沒有參數圓括號的版本中,三元數據得到評估並且respond_to?檢查"hello"或「再見」。在第二種情況下,代碼執行你的打算。

沒有括號:

# @ NODE_SCOPE (line: 1) 
# +- nd_tbl: (empty) 
# +- nd_args: 
# | (null node) 
# +- nd_body: 
#  @ NODE_FCALL (line: 1) 
#  +- nd_mid: :puts 
#  +- nd_args: 
#   @ NODE_ARRAY (line: 1) 
#   +- nd_alen: 1 
#   +- nd_head: 
#   | @ NODE_FCALL (line: 1) 
#   | +- nd_mid: :respond_to? 
#   | +- nd_args: 
#   |  @ NODE_ARRAY (line: 1) 
#   |  +- nd_alen: 1 
#   |  +- nd_head: 
#   |  | @ NODE_IF (line: 1) 
#   |  | +- nd_cond: 
#   |  | | @ NODE_CALL (line: 1) 
#   |  | | +- nd_mid: :to_sym 
#   |  | | +- nd_recv: 
#   |  | | | @ NODE_STR (line: 1) 
#   |  | | | +- nd_lit: "greeting" 
#   |  | | +- nd_args: 
#   |  | |  (null node) 
#   |  | +- nd_body: 
#   |  | | @ NODE_STR (line: 1) 
#   |  | | +- nd_lit: "hello" 
#   |  | +- nd_else: 
#   |  |  @ NODE_STR (line: 1) 
#   |  |  +- nd_lit: "bye" 
#   |  +- nd_next: 
#   |   (null node) 
#   +- nd_next: 
#    (null node) 

有了:

# @ NODE_SCOPE (line: 1) 
# +- nd_tbl: (empty) 
# +- nd_args: 
# | (null node) 
# +- nd_body: 
#  @ NODE_FCALL (line: 1) 
#  +- nd_mid: :puts 
#  +- nd_args: 
#   @ NODE_ARRAY (line: 1) 
#   +- nd_alen: 1 
#   +- nd_head: 
#   | @ NODE_IF (line: 1) 
#   | +- nd_cond: 
#   | | @ NODE_FCALL (line: 1) 
#   | | +- nd_mid: :respond_to? 
#   | | +- nd_args: 
#   | |  @ NODE_ARRAY (line: 1) 
#   | |  +- nd_alen: 1 
#   | |  +- nd_head: 
#   | |  | @ NODE_CALL (line: 1) 
#   | |  | +- nd_mid: :to_sym 
#   | |  | +- nd_recv: 
#   | |  | | @ NODE_STR (line: 1) 
#   | |  | | +- nd_lit: "greeting" 
#   | |  | +- nd_args: 
#   | |  |  (null node) 
#   | |  +- nd_next: 
#   | |   (null node) 
#   | +- nd_body: 
#   | | @ NODE_STR (line: 1) 
#   | | +- nd_lit: "hello" 
#   | +- nd_else: 
#   |  @ NODE_STR (line: 1) 
#   |  +- nd_lit: "bye" 
#   +- nd_next: 
#    (null node) 
5

如果沒有括號,看來你的代碼被這樣解釋:

puts respond_to?("greeting".to_sym ? "hello" : "bye") 

在括號中的東西然後評價爲「你好」,而self顯然沒有迴應,所以respond_to?返回false

這就是爲什麼每當對代碼的操作順序有任何疑問時使用括號總是一個好主意;它使您的代碼更具可讀性並消除諸如此類的錯誤。