Examples of reflection (Reflection) applications in Ruby _ruby topics

Source: Internet
Author: User
Tags class definition reflection

In the Java language, a launch mechanism is provided by which the object can be constructed from a string, can get all the methods of the object (including private methods), can invoke the private method, and can change the value of the member variable (including the private member variable).
Ruby is also an object-oriented high-level language and, of course, provides a reflection mechanism, and today we discuss the ability to construct class objects through class names.

Constructing class objects by class name

Let's look at the ordinary structure:

Copy Code code as follows:

Module Modulea

#the class name, later we use it to create the corresponding object

Class_name_of_wood = "Modulea::wood"

Class_name_of_wooddesk = "Modulea::wooddesk"

Class_name_of_woodchair = "Modulea::woodchair"


Class Wood

DEF initialize

@desc = "I am a primal wood"

End


DEF say

Puts @desc

End

End


Class Wooddesk < Wood

DEF initialize

@desc = "I am a desk made of wood"

End


def say_private

Puts "Actually, I have some bug but no public"

End


Public:say

Private:say_private


End


Class Woodchair < Wood

DEF initialize

@desc = "I am a chair made of wood"

End


def say_private

Puts "I Want get married with a wooddesk ..."

End


def smile

Puts "ha hah hah haha ..."

End


Public:say

Private:say_private,: Smile

End

End

Defines a basic class wood, which has two subclasses: Wooddesk, Woodchair, and subclasses that have a private method say_private respectively.
We new objects to execute:

Copy Code code as follows:

#the Normal Initailze

Wood = Modulea::wood.new

Wood.say

Desk = Modulea::wooddesk.new

Desk.say

Chair = modulea::woodchair.new

Chair.say


#try Call the Private method

Puts "desk respond to say_private?" #{desk.respond_to?: say_private} "

Desk.say_private if desk.respond_to? : Say_private

The code above, executes the public method say, and then attempts to execute the private method say_private, whether the execution of the check is possible, and the return result is not enforceable, desk.respond_to? : Say_private returns false:

Copy Code code as follows:

I am a primal wood

I am a desk made of wood

I am a chair made of wood

Desk respond to say_private? False

OK, now we construct the object through the reflection mechanism and try to execute its private method.

We notice that there are three constants in the definition of the module, which is defined as the class name,

Copy Code code as follows:

#the class name, later we use it to create the corresponding object

Class_name_of_wood = "Modulea::wood"

Class_name_of_wooddesk = "Modulea::wooddesk"

Class_name_of_woodchair = "Modulea::woodchair"


The following three variables are used to understand the Module.constants method.

The following code fragment is based on the class definition above:

Copy Code code as follows:

#get All Module Constants

Obj_list = Array.new

Tmp_const_sym_list = modulea.constants

Tmp_const_sym_list.each do | Sym |

Obj_list << Modulea.const_get (sym)

Puts "CALSS = #{sym.class}, value = #{sym}"

End

We note that modulea.constants, which is in module modules, acts as a symbol object that returns all the constants in the module. We look at the result output:

Copy Code code as follows:

CALSS = Symbol, value = Class_name_of_wood

CALSS = Symbol, value = Class_name_of_wooddesk

CALSS = Symbol, value = Class_name_of_woodchair

CALSS = Symbol, value = Wood

CALSS = Symbol, value = Wooddesk

CALSS = Symbol, value = Woodchair

As you can see from the results, the three constants and class names that are defined are returned. So note: The constants in Ruby are the constants (variables) and class names that contain the definitions, and note that they are all symbol objects ...

But we need to construct the class object based on the class name, then the three constants are useless and need to be deleted. We filter by using regular expressions to match names. The code above modifies:

Copy Code code as follows:

#get All Module Constants

Sym_list = Array.new

Tmp_const_sym_list = modulea.constants

Tmp_const_sym_list.each do | Sym |

Puts "CALSS = #{sym.class}, value = #{sym}"

Sym_list << Modulea.const_get (sym) if/^wood\w*/=~ sym.to_s

End

Sym_list << Modulea.const_get (sym) if/^wood\w*/=~ sym.to_s, save only the symbol at the beginning of Wood, so that we filter out the three constants.

After looking for both class names, start constructing the object:

Copy Code code as follows:

#create object from Symbol

Obj_list = Array.new

Sym_list.each do | Sym |

obj = sym.new

Obj_list << obj

Puts "Create the object: #{obj}"

End


Begin

Obj_list.each do | Wood |

Wood.say

End

Call the new method of symbol to construct the secondary object (sym.new), and then we call the object's say method:

Copy Code code as follows:

Create the object: #

Create the object: #

Create the object: #

I am a primal wood

I am a desk made of wood

I am a chair made of wood

Achieved the results we had expected.

Operation member variables and private methods

Students who have used Java reflection know that with objects, manipulating member variables and private methods is a cinch.
The same is true in Ruby.

Look at the example of an operation member variable first. We tried to change the value of a member variable. (followed by the code of an article)

Copy Code code as follows:

#manpulate instance variables

First_wood = Obj_list.first

First_wood.instance_variables.each do | var |

#get the instance variable

Puts "class of var = #{var.class}, value of var = #{var}"

Var_value = First_wood.instance_variable_get (Var)

Puts "class of Var_value = #{var_value.class}, value of Var_value = #{var_value}"


#set the new value of instance Varialbe

First_wood.instance_variable_set (Var, var_value + "... and I was changed.")

First_wood.say

End

1, First_wood.instance_variables.each, we get a wood object, and then call its Instance_variables method to get the names of all the member variables (symbol objects).
2, then, call the object's First_wood.instance_variable_get method, pass the member variable name, get the member variable object.
3, finally, we change the value of this member variable through First_wood.instance_variable_set.
Code Run Results:

Copy Code code as follows:

Class of var = Symbol, value of var = @desc

Class of Var_value = String, value of Var_value = I am a primal wood

I am a primal wood...and I was changed.

Then look at the calling private method:

Copy Code code as follows:

#call Private Method

Last_wood = Obj_list.last

Last_wood.method (: say_private). Call

Quite simply, if you know the method name, call Last_wood.method the method name, you can get a methods object and call the method object, and the result is the contents of the private method output:

Copy Code code as follows:

I Want get married with a wooddesk ...

There is no way to modify a member variable and invoke a private method in a normal scenario, because it violates the object-oriented encapsulation principle, so what scenario is reflection useful? From my personal experience, I think two places are useful:
1) Unit Test.
2 aspect-oriented programming.
Both scenarios need to invoke the private method or replace the value of the member variable.

What do you think?

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.