Knowledge not found in Ruby metaprogramming books define_method

Source: Internet
Author: User
How many methods do you have to create a method? Most people may think of the def keyword Ruby. Code
    1. # Common method
    2. DefTele_you
    3. Puts"I am anleb"
    4. End
 
# General method def tele_you puts "I am anleb" End
Ruby code
    1. # Define a single-piece Method
    2. N ="Anleb"
    3. DefN. tell_you
    4. Puts"I am # {self }"
    5. End
    6. N. tell_you
 
# Define the single-piece method N = "anleb" def N. tell_you puts "I am # {self}" endn. tell_you

Ruby code

    1. # define_method
    2. class project
    3. define_method : tell_you DO | Name |
    4. puts name
    5. end
    6. end
    7. A = project. New
    8. . tell_you ( "anleb" )
# Define_methodclass project define_method: tell_you do | Name | puts name endenda = project. newa. tell_you ("anleb ")

Specific analysis: define_method Ruby code

    1. Kernel. private_methods.include? ("Define_method")# True
 
Kernel. private_methods.include? ("Define_method") # True

We can see that define_method is a private method, so there are rules for calling Private methods:
1. There cannot be explicit calls, that is, there cannot be recipients, and there cannot be calls like self. define_method.
2. Private methods can be inherited.
3. Private methods can be forcibly called by "send", for example, "Send (: private_method)
4. Only private methods can be called in itself (understand the meaning of this sentence)

In the project class above, the current self is a class project, and then the define_method method is called implicitly to createCubeMethod

Define_methods dynamic creation method. What is dynamic creation? It means that a method is created and defined during code runtime. Using Dynamic Creation and dynamic distribution, Ruby code reconstruction can be realized. This is magic!
The example meta-programming book contains 46 Chinese versions and 69 English versions.

Let's look at an example:

  1. ClassProject1
  2. Define_method : Tell_you Do| Name |
  3. Puts name
  4. End
  5. End
  6. ClassProject2 <project1
  7. End
  8. A = project2.New
  9. A. tell_you ("Anleb")
  10. Project1.instance _ methods (False)# ["Tell_you"]
 
Class project1 define_method: tell_you do | Name | puts name endendclass project2 <project1 ENDA = project2.newa. tell_you ("anleb") project1.instance _ methods (false) # ["tell_you"]

1. It indicates that the methods defined by define_method are no different from those defined by def and can be inherited.
2. The define_method method is an instance method that exists in the class.

Code modification: Ruby code

  1. ClassProject1
  2. Define_method : Tell_you Do| Name |
  3. Puts name
  4. End
  5. DefCreat_method
  6. Define_method : New_method Do
  7. Puts"This is a new method"
  8. End
  9. End
  10. End
  11. Project1.New. Creat_method
  12. Error: Test. RB: 7: In'Creat _ Method': Undefined method' DEFINE _ Method' For # <Project1: 0x2bc7008> (nomethoderror)
 
Class project1 define_method: tell_you do | Name | puts name end def creat_method define_method: new_method do puts "this is a new method" End endendproject1.new. creat_methoderror: test. RB: 7: In 'creat _ method': Undefined method 'define _ method' for # <project1: 0x2bc7008> (nomethoderror)

I forgot to say that define_method is the object class method, that is, only the class can be called,
The current self of creat_method must be an object. The object is not a class, so it cannot be called. modify the code.

    1. def creat_method
    2. Self . class . define_method : new_method DO
    3. puts "this is a new method"
    4. end
    5. end
Def creat_method self. Class. define_method: new_method do puts "this is a new method" end

Call method:

    1. Project1.New. Creat_method
    2. Error: Test. RB: 7: In'Creat _ Method': Private method 'define _ Method'CalledForProject1:Class(Nomethoderror)
 
Project1.new. creat_methoderror: Test. RB: 7: In 'creat _ method': Private method 'define _ method' called for project1: Class (nomethoderror)

Crash, why not? Let's take a look at the prompt, saying this is a private method, amount... Forget that the private method cannot explicitly have a receiver. Let's think of a method, right, that is, the send method.

Modify the Code:

  1. ClassProject1
  2. Define_method : Tell_you Do| Name |
  3. Puts name
  4. End
  5. DefCreat_method
  6. Self.Class. Send (: Define_method,: New_method)Do
  7. Puts"This is a new method"
  8. End
  9. End
  10. End
  11. A = project1.New
  12. P project1.instance _ methods (False)# ["Creat_method", "tell_you"]
  13. A. creat_method
  14. P project1.instance _ methods (False)# ["Creat_method", "tell_you"]
 
Class project1 define_method: tell_you do | Name | puts name end def creat_method self. class. send (: define_method,: new_method) do puts "this is a new method" End endenda = project1.newp project1.instance _ methods (false) # ["creat_method", "tell_you"]. creat_methodp project1.instance _ methods (false) # ["creat_method", "tell_you"]

Finally, it succeeded. This technology is called the dynamic distribution technology, which is commonly used in the method_messing method.

Solution 2: Java code

  1. ClassProject1
  2. Define_method: tell_youDo| Name |
  3. Puts name
  4. End
  5. Def self. creat_method
  6. Define_method: new_methodDo# The current self is a class, so it can be called and implicitly
  7. Puts"This is a new method"
  8. End
  9. End
  10. Creat_method
  11. End
  12. Project1.New. New_method
 
Class project1 define_method: tell_you do | Name | puts name end def self. creat_method define_method: new_method do # The current self is a class, so it can be called, and the implicit puts "this is a new method" end creat_methodendproject1.new.new_method

Solution 3: Ruby code

  1. ClassProject1
  2. Class<Self
  3. DefCreat_method
  4. Define_method : New_method Do# Current self is a class
  5. Puts"This is a new method"
  6. End
  7. End
  8. End
  9. Creat_method
  10. End
  11. Project1.New. New_method
Class project1 class <self def creat_method define_method: new_method do # The current self is a class puts "this is a new method" end creat_methodendproject1.new.new_method

The research is not good. If you have any mistakes, please contact us!

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.