Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the Refinements features in Ruby2.1

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "what are the Refinements features in Ruby2.1". In daily operation, I believe many people have doubts about what are the Refinements features in Ruby2.1. Xiaobian consulted various materials and sorted out simple and easy operation methods. I hope to help you answer the doubts about "what are the Refinements features in Ruby2.1"! Next, please follow the small series to learn together!

Monkey Patches have always been a side effect of Ruby's Open Class feature, although some people see Monkey Patches as a Ruby feature. Why is it called Monkey Patch? Evolution is incomplete, this is also a name passed from the Ruby community, no matter what, this name represents derogatory, meaning danger.

Ruby's open classes give developers a lot of freedom and flexibility, but when you open a class and add your own methods, have you ever thought that this method will overwrite existing methods? Your own code is fine, but if you use Ruby's built-in classes, or classes provided by third-party gems, Monkey Patches may let your code cross at any time.

There is a typical case, before the early Ruby 1.8.7 preview version, there was no Symbol#to_proc method, but Rails itself implemented the Symbol#to_proc method through Monkey Patch, and the Symbol#to_proc method was added after Ruby 1.8.7 preview version, resulting in some problems with Rails.

Before Refinements, the Ruby community avoided Monkey Patches in the following ways:

Use alias/ alias_method_chain

Use module plus namespace

Force check if the method to be added is defined

The Refinements feature, which has been discussed in the Ruby community for years, is designed to solve this problem and allow you to use open classes safely. This feature wasn't added until Ruby 2.0, but it was experimental and not recommended, but two days ago with the release of Ruby 2.1 stable version, the Refinements feature was released from experimental state, which means that the Ruby team supports recommending you to use the Refinements feature, but more tragically, the Refinements documentation didn't keep up, you have to read the documentation to learn this new feature, most likely errors.

Below I summarize the general usage of Refinements in Ruby 2.1. Please let me know if there are any omissions.

1. The way ordinary youth use Refinements: # refinements provides a way to make class modifications affect only a certain scope #Determine whether a string is a numeric string module NumberQuery refine String do def number? !! match(/^[0-9]+$/) end end #is not defined as class A def a(n) n.respond_to? (:number?) endendA.new.a "123" #=> This returns false, meaning no number is defined. Method #You have to use Module#using method class A using NumberQuery end#You think opening class A using NumberQuery is enough? You're naive. A.new.a "123" #=> false#See clearly, you must redefine A#a method class A using NumberQuery def a(n) n.respond_to? (:number?) #=> true endA.new.a "123" #=> returns true, proves number? The method works.

It can be seen that you used the Module#refine method to open the class to add methods, and can only use the Module#using method to introduce patch modules where this patch is needed. Also, note that in the example code above, you have to use NumberQuery in the original place of the class definition for it to work. This is somewhat similar to the concept in java or.net. Classboxes, where changes to a classbox are visible only to the classbox itself (or to the classbox into which it was imported). This feature is called local rebinding. MS in C#also has a using for extension methods, C#extension methods are only visible in the code they explicitly import, similar to our Ruby example above. So Refinements in Ruby is an improved version of Classboxes.

module NumberQuery refine String do def number? !! match(/^[0-9]+$/) end endend

Then:

class String using NumberQuery def other_method puts "hello" if number? endend

Of course, this does not cause global pollution of the String class, limited to other_method methods, but please note that you do not have the inertia to open the class for Monkey Patches?

Some might use it like this:

class T refine String do def number? !! match(/^[0-9]+$/) end endend

Brother, please, this is wrong:

NoMethodError: undefined method `refine' for T:Class

This means that you cannot use refine in a class.

There was also someone who was a little clever. He used it like this:

#This module of mine, it's not just patching ah, there are other methods module NumberQuery refine String do def number? !! match(/^[0-9]+$/) end end def hello puts "world".number? end #Then I have to include class A using NumberQuery include NumberQueryend in addition to using

This is not working, or to learn the use of ordinary youth, NumberQuery#hello method used in the number? Is illegal.

Some people are thinking, how troublesome this is, I have to write the name of the module twice, there, I use the included method:

module NumberQuery def self.included(base) base.send(:using, self) end refine String do def number? !! match(/^[0-9]+$/) end end def hello puts "world" end #This way, I can include NumberQuery module only once. class A include NumberQueryend

Stop it, brother, you've done it again. Open your eyes and see what mistakes you've made!

A brother wants to define a class method:

module NumberQuery refine String do def self.number? (str) !! str.match(/^[0-9]+$/) end endendclass A using NumberQuery def a String.number? ("123") endendA.new.a #=> NoMethodError: undefined method `number? ' for String:Class

Are you dumbfounded? Oh, tell you the correct definition of class method usage:

module NumberQuery refine String.singleton_class do def number? (str) !! str.match(/^[0-9]+$/) end endendclass A using NumberQuery def a String.number? ("123") endendA.new.a #=> true

This time it was normal.

Refinements also have a place where Rubyist easily commits two mistakes, that is, if you refine the method, if you have the same name as the method in the class, you will still rewrite that method. Of course, you can also use super.

module NumberQuery refine String do def to_s to_i end endendclass A using NumberQuery def a "123".to_s endend

String#to_s method has been modified, alas, is this the rhythm of Monkey Patches again? No. It is useful only in A#a and does not pollute the whole situation, but you must pay attention when you encounter similar situations. Of course, subclasses in A will also be passed down unless method a is rewritten.

class B

< A; endB.new.a #=>

123#When in subclass B, after overriding a method: class B

< A def a "123".to_s endendB.new.a #=>

"123"#unless you also use refine patches in class B

< A using NumberQuery def a "123".to_s endendB.new.a #=>

123

It is also worth noting that the module of using is not hung on the inheritance tree (ancestors tree):

module NumberQuery refine String do def number? !! match(/^[0-9]+$/) end endendclass A using NumberQuery def a "123".number? endendA.ancestors #=> [A, Object, Kernel, BasicObject]

As you can see, NumberQuery isn't hanging on the ancestor tree.

At this point, the study of "What are the Refinements features in Ruby 2.1" is over, hoping to solve everyone's doubts. Theory and practice can better match to help everyone learn, go and try it! If you want to continue learning more relevant knowledge, please continue to pay attention to the website, Xiaobian will continue to strive to bring more practical articles for everyone!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report