Ruby元編程小結(三)

Ruby元編程小結(三)

1. 動態調用
當你調用一個方法時,實際是給一個對象發送了一條消息。
class MyClass
    def my_method(args)
        args * 10
    end
end
obj = MyClass.new

puts obj.my_method(5)
puts "**"
puts obj.send(:my_method, 6)

result =>
50
**
60
可使用object#send()取代點標記符來調用MyClass#my_method()方法:
obj.send(:my_method, 6)
send()方法第一個參數是要發送給對象的消息,能夠是符號(:symbol)或字符串,其餘參數會直接傳遞給調用的方法。
能夠動態的決定調用哪一個方法的技術,成爲Dynamic Dispatch。

符號和字符串的區別:
1. 符號不可變,能夠修改字符串中的字符。
2. 針對符號的操做更快些。
3. 一般符號用來表示事物的名字。
例如:
puts 1.send(:+, 4) => 5
String#to_sym(),String#intern()    =>    string to symbol
String#to_s(),String#id2name()    => symbol to string
"caoqing".to_sym() => :caoqing
:caoqing.to_s() => "caoqing"
動態派發中使用模式派發(pattern dispatch)的方法。
puts obj.class.instance_methods(true).delete_if{ |method_name| method_name !~ /^my/}
result => 
my_method

2. 動態定義
使用Module#define_method()方法定義一個方法。
class MyClass
    define_method :my_method do |args|
        args * 3
    end
end
obj = MyClass.new
puts obj.my_method(10)
result =>
30

附錄:
類變量,實例變量,類方法,實例方法區別
@@                            :var類變量
@                            :實例變量
self(?clas,::).method        :類方法
method                        :實例方法
# test.rb
class Foo
    @@var = "lion"
    def self.method01
        puts "cat"
        @name = "cat"
        @@var = "cat"
        puts @name
    end

    def self.method02
        puts "tiger"
        @name = "tiger"
        @@var = "tiger"
        puts @name
    end

    def self.method03
        puts "dog"
        @name = "dog"
        @@var = "dog"
        puts @name
    end

    def putsname
        puts @name
        puts @@var
    end
end

obj = Foo.new
# obj.method01            =>    (NoMethodError)

obj.putsname            =>    lion

Foo.method01
Foo.method02
Foo.method03
obj.putsname

result =>

lion
cat
cat
tiger
tiger
dog
dog

dog
相關文章
相關標籤/搜索