The nuances of Ruby's Def and Define_method

Source: Internet
Author: User

In the Ruby language, the specific differences between Class_eval and Instance_eval are obvious, Class_eval is for a class object, and the instance method can be defined in this object. While Instance_eval is for an object, the class opened is Eigenclass or 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

At this point, we define the class method of a, which means that we define an instance method (instance) "Hello" in A.eigenclass.

A.hello # Hello

A.world # nomethoderror:undefined method ' World ' for A:class

A.new.world # Hello


To this point, everyone feels better to understand.

Now the following question is coming,

A.instance_eval do

Define_method (: T1) do

Puts "T1"

End

End

According to many people, Define_method and the def mechanism are similar, but def is more efficient, define_method is a dynamic definition method, and Define_method can use local variables.

So, we analyze from above, method: T1 should still be a Eigenclass instance method, or the class method of a.

A.T1 should output "T1"

But the actual is:

nomethoderror:undefined method ' T1 ' for A:class

A.NEW.T1 # t1

Therefore, under the Instance_eval, Define_method and Class_eval are consistent, both of which define a case method.

And if we write like this,

Class <<a

Define_method (: T2) do

Puts "T2"

End

End

A.T2 # t2

The above method does define the instance method T2 in A.eigenclass.

At the beginning of this article, we said that when A.instance_eval really opened the Eigenclass, why is it correct for def and not for Define_method? Define_method is also logical when class << A shows open Eigenclass.

Perhaps to facilitate the writing of the meta-method, made this intentional adjustment.

Klass.instance_eval Do

      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


In the above code, the Klass is defined, and most of this writing code, the dynamic generation method is to generate the instance method, rather than the Klass class method, so, define_method at this time, made a special change, This introduces a special exception to the rules we have previously summarized. If you do not introduce a special exception, then you must add a wrapper layer, klass.class_eval do ... end to do the processing.


The nuances of Ruby's Def and Define_method

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.