ruby的def 和 define_method的細緻差別

來源:互聯網
上載者:User

標籤:ruby   singleton   

        ruby語言中,class_eval和instance_eval的具體差別比較明顯, class_eval針對的是一個Class的對象,然後在此對象中可以定義instance方法。而instance_eval是針對某個對象,開啟的class是 eigenclass或者singleton class。

class A 

end

A.instance_eval do

     def hello

        puts "hello"

     end

end

A.class_eval do

     def world

         puts "world"

     end

end

此時,我們定義的是A的class方法,也就是說我們在A.eigenclass中定義了一個執行個體方法(instance method)"hello".

A.hello   # hello

A.world  # NoMethodError: undefined method `world‘ for A:Class

A.new.world # hello


到這一點為止,大家都感覺比較好明白。

現在下面的問題來了,

A.instance_eval do

   define_method(:t1) do

       puts "t1"

   end

end

按照很多人說法,define_method和def機制類似的,只是def更高效,define_method是動態定義方法而已,並且define_method可以使用局部的變數。

所以,我們從上面分析,方法:t1 應該還是A的eigenclass的執行個體方法,或者說A的類方法。

A.t1  應該輸出 "t1"

但實際是:

NoMethodError: undefined method `t1‘ for A:Class

A.new.t1 # t1

所以在instance_eval下,define_method 和 class_eval 是一致的,都是定義了A得執行個體方法。

而如果我們這樣寫,

class <<A

    define_method(:t2) do

       puts "t2"

    end

end

A.t2 # t2

上面這種方法確實是在A.eigenclass中定義了執行個體方法 t2。

在這篇文章開頭,我們說過,A.instance_eval 確實開啟的時eigenclass, 為什麼對def是正確地,而對define_method是不對的呢? 而在class << A 這種顯示開啟eigenclass時, define_method也是符合邏輯的。

或許是為了方便寫meta方法,做了這種有意的調整。

klass.instance_evaldo

      method_object = instance_method(method)

     define_method(method)do |*args, &block|
                puts "==> calling #{method} with #{args.inspect}"

               result = method_object.bind(self).call(*args, &block)

              puts "<== #{method} returned #{result.inspect}"

              result

      end

end 


在上面這段代碼裡,對klass做了定義方法,而大部分這種寫代碼而言,動態產生方法都是想產生執行個體方法,而不是klass的類方法,所以,define_method在這個時候,做了特殊的變化,從而把我們先前總結的規律給引入了一個特殊的例外。如果不引入特殊的例外,這時,必須再加一個封裝層, klass.class_eval do   ....  end 來做處理。


ruby的def 和 define_method的細緻差別

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.