2017-08-09 30 views
0

我與紅寶石(2.4.1p111)實驗和與負載方法,它確實有一些奇怪的行爲:紅寶石負載不看靜態方法的類

我有兩個文件:

mytest.rb

class MyClass 

    def self.greet(param) 
    puts "Got called: #{param}" 
    end 

    greet 'Called locally' 

    load "./testld.rb" 
end 

和加載的文件:

testld.rb

greet 'Called by load' 

我從從testld.rb加載代碼,並就在MyClass的方法調用應該表現相同文件的理解。相反,我得到:

-bash-4.2$ ruby mytest.rb 
Got called: Called locally 
/Blacksmith/RB/testld.rb:1:in `<top (required)>': undefined method `greet' 
for main:Object (NoMethodError) 
    from mytest.rb:9:in `load' 
    from mytest.rb:9:in `<class:MyClass>' 
    from mytest.rb:1:in `<main>' 

任何想法我做錯了什麼?

+1

你能指出給你留下這種理解的文檔嗎?這不是它的工作原理。如果它包含在'testld.rb'中的'MyClass'中,它將被調用,就像它一樣。如果不是,它不會,無論你在哪裏加載它。 – ndn

+0

https://ruby-doc.org/core-2.4.1/Kernel.html#method-i-load 我錯誤地認爲加載的代碼是在MyClass的上下文中執行的。 @MatayoshiMariano指出MyClass.greet的工作。 – Pavel

+0

@Pavel「我錯誤地認爲加載的代碼是在MyClass的上下文中執行的。」這不是MatayoshiMariano指出的。這個答案忽略了這一點。 – sawa

回答

2

您需要撥打testld.rb中的MyClass.greet,這是因爲greet是類MyClass中定義的類方法。

Here是類方法的文檔。

+0

這個作品,謝謝! – Pavel

+0

@Pavel它的工作原理是巧合。這個答案與你的實際問題無關。 – sawa

+0

這個答案中提到的任何特定於Ruby 2.4的標籤,其標籤MatayoshiMariano添加到建議的編輯? – sawa

2

無論您在何處加載文件,都會在主環境中評估加載的文件。在testld.rb的主要環境中,self的值是整個腳本的主要環境。因此,您的

greet 'Called by load' 

不等同於

MyClass.greet 'Called by load' 

如你預期。

+0

我真正想要實現的是使用靜態方法,即 MyClass.greet。 我認爲加載的工作類似於C預處理器,將文件內容放入MyClass然後執行,這是錯誤的。 – Pavel

+1

你已經定義了'MyClass.greet'。那部分,你做得對。你做錯了什麼是你稱呼它的方式。這是對它的解釋。 – sawa

+2

@Pavel不要把Ruby當成花哨的C.它是Smalltalk的起源,它有不同的方法來解決這樣的問題。如果你在你的課堂上創建了一個'module'和'include',你就可以通過'included'方法來連接,並且一切都可以無縫工作。 – tadman