我真的很陌生,所以這是一個入門級的問題。
簡短的回答是:Bob類中的login()實例方法隱藏了頂級login()方法。簡單的解決方案是:更改其中一種方法的名稱。
這裏有一些事情你應該嘗試學習:
1)在Ruby中,每一個方法被調用,在左邊的對象,例如
some_obj.login
在左手側上的對象被稱爲接收機。
2)如果您沒有明確指定接收者,例如
login('bob',pass) #No receiver is specified on the left hand side
...紅寶石使用稱爲自在左手側的變量,例如:在內部的方法
self.login('bob', pass)
3)一類中定義的,例如:
class Bob
def login(pass)
#IN HERE
end
end
...自我等於調用該方法的對象。你的情況,你有這樣的代碼:
bob = Bob.new
bob.login('world')
所以鮑勃是調用登錄()實例方法的對象,因此,你有這樣的:
class Bob
def login(pass)
#IN HERE, self is equal to bob
end
end
因此,紅寶石做到這一點:
class Bob
def login(pass)
#login('bob', pass) =>This line gets converted to this:
self.login('bob',pass) #ERROR#
#IN HERE, self is equal to bob
#So ruby executes this:
#bob.login('bob', pass) #ERROR: too many arguments#
end
end
一個解決您的問題,像吉列爾梅·卡洛斯建議,是使用一個模塊 - 但你可以做,在一個簡單的方法:
module MyAuthenticationMethods
def login(user, pass)
puts "user: #{user}, pass: #{pass}"
end
end
class Bob
def login(pass)
MyAuthenticationMethods::login('bob',pass)
end
end
但是,通常你把一個模塊放在它自己的文件中,然後require
它。模塊解決您的問題的原因是模塊名稱以大寫字母開頭,這意味着它是一個常量 - 您可以從代碼中的任何位置訪問常量。
4)所有的def都附在當前類別上。當前類由self變量的值決定:如果self是一個類,那麼當前類只是self的值,但是當self不是一個類時,那麼當前類是self的類。好吧,讓我們來看看這些原則在行動:
class Bob
puts self #=>Bob
def login(pass)
...
end
end
因爲自我是一個類,當前類等於自我,和DEF附有自己的鮑勃類。
頂級會發生什麼?
puts self #=> main
def login(user,pass)
end
有經驗的紅寶石主義者熟悉main
;它是ruby在頂層(即任何類或方法定義之外)指定給自己的對象 - 您在調用的內容是global。重要的一點是main
不是一個類。其結果是,頂級登錄()DEF本身重視主要的類,它是:
puts self #=>main
puts self.class #=>Object
def login(user,pass)
end
布賴恩·德里斯科爾提到,紅寶石不具有全局範圍 - 但這並不真的事,因爲反正def創建了一個新的作用域,它關閉了外部作用域,因此def之外的任何東西都不會在def內部可見(常量除外)。
你正在做的事通常是用紅寶石完成的,所謂的塊。塊允許您將第二種方法傳遞給第一種方法,然後在第一種方法中您可以調用第二種方法。這裏有一個例子:
class Bob
def login(pass)
yield('bob', pass) #yield calls the block with the specified arguments
end
end
bob = Bob.new
bob.login('my password') do |username, pword|
puts username, pword
end
在該代碼塊是這一部分:
do |username, pword|
puts username, pword
end
...這看起來有點像一個方法定義 - 但沒有一個名字。這是頂級login()方法的替身。紅寶石會自動將塊的塊之前規定的方法:
This method!
|
V
bob.login('my password')
和登錄()方法中,你使用這個詞yield
--IT的調用該塊,就好像yield
是該方法的名稱。
請注意,它實際上是ruby的sytnax,即在方法調用後編寫塊,導致第二個方法傳遞給第一個方法,並且在第一個方法中,您可以通過簡單地編寫yield(arg1, arg2, etc.)
。
Ruby實際上並沒有全局範圍。您的第一個登錄定義實際上將作用域爲Object。檢查出這個問題的接受答案:http://stackoverflow.com/questions/1042384/how-do-you-use-global-variables-or-constant-values-in-ruby – 2014-11-06 19:47:34
@BrianDriscoll:你指的是到錯誤的問題。此問題是[此問題]的重複(https://stackoverflow.com/questions/9593514/how-to-call-a-method-from-the-global-scope-with-same-name-as-an-實例方法)。 – Surya 2014-11-06 19:59:25
或這個問題:https://stackoverflow.com/questions/2681895/how-to-access-a-shadowed-global-function-in-ruby – Surya 2014-11-06 20:03:01