One of Ruby's magical learning notes _ruby topics

Source: Internet
Author: User
Tags extend instance method
send message to object display
We can send a message directly to the object:
Ruby Code
Copy Code code as follows:

Class HelloWorld
def say (name)
Print "Hello,", name
End
End
HW = Helloworld.new
Hw.send (: Say, "world")

We usually use Hw.say ("World"), but send can work on private methods.
Not only so send can make the program more dynamic, let's take a look at an example:
We have defined a class person, and we want an array that contains the person object to be able to press
Sort according to any member data of person:
Ruby Code
Copy Code code as follows:

Class Person
Attr_reader:name,:age,:height
def initialize (name,age,height)
@name, @age, @height = Name,age,height
End
def inspect
# @name # @age # @height.
End
End
Any class in Ruby can be opened at any time, so that it can be written in such a graceful way as 2.days_ago
Code, we open the array and define a sort_by method:
Ruby Code
Class Array
def sort_by (Sysm)
self.sort{|x,y| x.send (sym) <=> y.send (SYM)}
End
End
Let's look at the results of the operation:
Ruby Code
People = []
People << person.new ("Hansel", 35,69)
People << person.new ("Gretel", 32,64)
People << person.new ("Ted", 36,68)
People << person.new ("Alice", 33, 63)
P1 = people.sort_by (: name)
P2 = people.sort_by (: Age)
P3 = people.sort_by (: height)
P P1 # [Alice, Gretel, Hansel, Ted 36 68]
P P2 # [Gretel, Alice, Hansel, Ted 36 68]
P P3 # [Alice, Gretel, Ted, Hansel 35 69]
How did this result get?
In fact, there's a place besides send that should be noted attr_reader,attr_reader equivalent to the definition of name,
Age,heigh three methods, and the sort method in the array only needs to provide a comparison method:
X.send (sym) <=> y.send (sym) Gets the property value of person by send, and then uses <=> compare
Two, a custom object
<< Object
Not only can Ruby open a class, but it can also open an object that adds or customizes functionality to the object without affecting
Other objects:
Ruby Code
A = "Hello"
b = "Goodbye"
def b.upcase
Gsub (/(.) (.) /) ($1.upcase + $)
End
Puts A.upcase #HELLO
Puts B.upcase #GoOdBye
We found that the B.upcase method was made into our own.
If you want to add or customize multiple features to an object, we don't want multiple def b.method1 def B.METHOD2 to do this
We can have a more modular approach:
Ruby Code
b = "Goodbye"
Class << B
def upcase # Create single
Gsub (/(.) (.) /) {$1.upcase + $}
End
def upcase!
gsub! (/(.) (.) /) {$1.upcase + $}
End
End
Puts B.upcase # GoOdBye
Puts B # goodbye
b.upcase!
Puts B # GoOdBye
This class is called Singleton class, because this class is for the object of B.
and design pattern Singleton object is similar, only occurs once of Dongdong we call Singleton.
<< self adds behavior to your defined class
Ruby Code
Class Theclass
Class << Self
def hello
Puts "hello!"
End
End
End
Theclass.hello #hello!
<<self modifies the class that you define class, which is a very useful technique, and he can define class levels
Helper method, which is then used in other definitions of this class. The following column child defines the access
function, we want to access the member data into a string, we can use this technique to
Define a Class-level method accessor_string:
Ruby Code
Class MyClass
Class << Self
def accessor_string (*names)
Names.each do |name|
Class_eval <<-eof
Def #{name}
@#{name}.to_s
End
Eof
End
End
End
DEF initialize
@a = [1, 2, 3]
@b = Time.now
End
ACCESSOR_STRING:A,: b
End
o = myclass.new
Puts O.A # 123
Puts O.B # Fri Nov 21 09:50:51 +0800 2008
By adding behavior to your object by extend module, the method inside the module becomes the object inside the
Instance method:
Ruby Code
Module quantifier
def any?
Self.each {|x| return TRUE if Yield X}
False
End
def all?
Self.each {|x| return FALSE if not yield X}
True
End
End
list = [1, 2, 3, 4, 5]
List.extend (quantifier)
Flag1 = List.any? {|x| x > 5} # False
Flag2 = List.any? {|x| x >= 5} # True
Flag3 = List.all? {|x| x <=} # True
Flag4 = List.all? {|x| x% 2 = 0} # False
Third, create a parameterized class:
If we're going to create many classes, these classes have only different initial values for class members, it's easy to think of:
Ruby Code
Class Intelligentlife # wrong way Todo this!
@ @home_planet = Nil
def intelligentlife.home_planet
@ @home_planet
End
def intelligentlife.home_planet= (x)
@ @home_planet = X
End
#...
End
Class Terran < Intelligentlife
@ @home_planet = "Earth"
#...
End
Class Martian < Intelligentlife
@ @home_planet = "Mars"
#...
End
This approach is wrong, and in fact the class members in Ruby are not only shared by all objects in this class,
Will actually be shared by the entire inheritance system, so we call terran.home_planet and output
"Mars", and what we expect is the Earth.
A feasible approach:
We can achieve the goal by delaying the evaluation at runtime by Class_eval:
Ruby Code
Class Intelligentlife
def intelligentlife.home_planet
Class_eval ("@ @home_planet")
End
def intelligentlife.home_planet= (x)
Class_eval ("@ @home_planet = #{x}")
End
#...
End
Class Terran < Intelligentlife
@ @home_planet = "Earth"
#...
End
Class Martian < Intelligentlife
@ @home_planet = "Mars"
#...
End
Puts Terran.home_planet # earth
Puts Martian.home_planet # Mars
The best way:
Instead of using class variables, we use class instance variables:
Ruby Code
Class Intelligentlife
Class << Self
Attr_accessor:home_planet
End
#...
End
Class Terran < Intelligentlife
Self.home_planet = "Earth"
#...
End
Class Martian < Intelligentlife
Self.home_planet = "Mars"
#...
End
Puts Terran.home_planet # earth
Puts Martian.home_planet # Mars
Iv. continuations in Ruby:
Continuations is probably the most difficult concept in Ruby, it can handle nonlocal jumps,
It saves the return address and execution environment, and is similar to setjmp and Longjump in C, but it saves
For more information:
Axgle Lift Cao's example is very image, we take over to see:
from [http://www.javaeye.com/topic/44271]
Caocao (Caocao) is known as "the Best of ancient Qinggong", because "speak of the Devil, Caocao to" this famous saying.
In Ruby, this kind of qinggong is called CALLCC.
Ruby Code
callcc{|caocao|
For say in ["Caocao", "Zhuge Liang", "Zhou Yu"]
Caocao.call if say== "Caocao"
Puts say #不会输出, because Cao has flown out.
End
}# "Cao" flew here (jumped out of the CALLCC block, immediately behind this block, continue to execute the following Ruby code)
Puts "to"
The Caocao in CALLCC is a "continuation" (continuation) object. This object has only one such method called Call.
When Caocao.call is executed, Caocao flies behind the CALLCC block, allowing Ruby to continue executing its code.
What I've given above is an example of "flying" from a block to a block; Here's an example of programming Ruby's "Fly" from behind the code to the code:
Ruby Code
arr = ["Freddie", "Herbie", "Ron", "Max", "Ringo"]
callcc{| $CC |} #下面的 $cc. Call, if executed, will fly back here (after the CALLCC block).
Puts (message = Arr.shift)
$CC. Call unless message =~/max/
Most examples come from <<the Ruby way>>
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.