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


你可能感兴趣的:(Ruby元编程小结(三))