Ruby magic learning notes

Source: Internet
Author: User

1. send messages to the object
We can directly send messages to objects:
Ruby code
Copy codeThe Code is 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.
In addition, sending can make the program more dynamic. Let's look at an example:
We have defined a class Person. We want an array containing the Person object to be
Sort by any member data of Person:
Ruby code
Copy codeThe Code is 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 as beautiful as 2. days_ago.
Code, we open 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 take a look at the running results:
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 33 63, Gretel 32 64, Hansel 35 69, Ted 36 68]
P p2 # [Gretel 32 64, Alice 33 63, Hansel 35 69, Ted 36 68]
P p3 # [Alice 33 63, Gretel 32 64, Ted 36 68, Hansel 35 69]
How can this result be obtained?
In fact, apart from sending, you should pay attention to attr_reader. attr_reader defines the name,
Age, heigh three methods, and the sort method in Array only needs to provide a comparison method:
X. send (sym) <=> y. send (sym) Get the property value of person through send, and then use <=> compare
2. Create an object
<Object
Ruby can not only open a class, but also open an object and add or customize features to this object without affecting
Other objects:
Ruby code
A = "hello"
B = "goodbye"
Def B. upcase
Gsub (/(.) (.)/) ($1. upcase + $2)
End
Puts a. upcase # HELLO
Puts B. upcase # GoOdBye
We found that the B. upcase method was customized as our own.
If you want to add or Customize multiple features to an object, we do not want to do this with multiple def B. method1 def B. method2.
We can adopt a more modular approach:
Ruby code
B = "goodbye"
Class <B
Def upcase # create single method
Gsub (/(.) (.)/) {$1. upcase + $2}
End
Def upcase!
Gsub! (/(.) (.)/) {$1. upcase + $2}
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 B.
Similar to the design pattern singleton object, singleton only occurs once.
<Self: Add behavior to your defined class
Ruby code
Class TheClass
Class <self
Def hello
Puts "hello! "
End
End
End
TheClass. hello # hello!
<Self modified the class you defined for the class. This is a very useful technique. It can define the class level.
And then use it in other definitions of this class. The following column defines the access
Function, we want to convert all member data into strings during access. We can use this technology
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
Using the extend module to add behavior to your object, the methods in the module become
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> 5} # false
Flag2 = list. any? {| X> = 5} # true
Flag3 = list. all? {| X <= 10} # true
Flag4 = list. all? {| X % 2 = 0} # false
3. Create a parameterized class:
If we want to create many classes, these classes only have different initial values of class members, we can easily remember:
Ruby code
Class IntelligentLife # Wrong way to do 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 method is incorrect. In fact, class members in Ruby are not only shared by all objects in this class,
In fact, it will be shared by the entire inheritance system, so we call Terran. home_planet and will output
"Mars", and what we expect is Earth
A feasible method:
We can achieve the goal through class_eval latency evaluation during runtime:
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 method:
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 to understand in Ruby. It can handle non-local redirects,
It saves the return address and execution environment, similar to setjmp and longjump in c, but it saves
For more information:
The example of Cao cited by axgle is very vivid. Let's take a look:
From [http://www.javaeye.com/topic/44271]
Caocao is hailed as the famous saying "the best man in ancient times" because "Cao, Cao.
In ruby, Cao is called callcc.
Ruby code
Callcc {| caocao |
For say in ["Cao", "Zhuge Liang", "Zhou Yu"]
Caocao. call if say = "Cao"
Puts say # No output, because Cao has already flown out
End
} # "Cao" flew here (jumping out of the callcc block, followed by the block and continuing to execute the following ruby code)
Puts ""
Caocao in callcc is a "Continuation" object. This object only has such a method called "call.
After caocao. call is executed, caocao will fly to the block of callcc and let ruby continue to execute the following code.
The above is an example of "Flying" from the block to the block outside. The following is an example of "Flying" from the back of the Code to the front of the Code provided by Programming Ruby:
Ruby code
Arr = ["Freddie", "Herbie", "Ron", "Max", "Ringo"]
Callcc {| $ cc |} # If the $ cc. call below is executed, it will fly back here (after the callcc block ).
Puts (message = arr. shift)
$ Cc. call unless message = ~ /Max/
Most examples are 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.