码迷,mamicode.com
首页 > Web开发 > 详细

RoR - MetaProgramming

时间:2019-04-12 13:40:07      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:tap   The   style   div   ghost   lin   temp   obj   rom   

ruby是动态语言,它有动态语言的优势与劣势

动态语言,像python与ruby 你不用提前去定义method - they need to only be "found" when invoked

calling method dynamically: 

class Dog
    def bark
         puts "Woof, woof!‘
    end
    def greet(greeting)
        puts greeting
    end
end

dog = Dog.new
dog.bark # => Woof, woof!
dog.send("bark") # => Woof, woof!
dog.send(:bark) # => Woof, woof!
method_name = :bark
dog.send method_name # => Woof, woof!

dog.send(:greet, "hello") # => hello

  Dynamic Dispatch:

  不需要call method 用 xxx.xxx 

  能用string和symbol call methods dynamically

 

优点:*can decide at runtime which methods to call 

           *The code doesn‘t have to find out until runtime which method it needs to call 

 

Dynamic method: 

class Whatever 
    define_method :make_it_up do 
        puts "Whatever..."
    end
end

whatever = Whatever.new 
whatever.make_it_up # => Whatever...

写动态方法能有效降低code量

require_relative store
class ReportingSystem 

    def initialize 
        @store = Store.new 
        @store.methods.grep(/^get_(.*)_desc/) { ReportingSystem.define_report_method_for $1 )
    end

    def self.define_repot_methods_for (item)
        define_method ("get_#{item}_desc") {@store.send("get_#{item}_desc) }
        define_method ("get_#{item}_price") {@store.send("get_#{item}_desc) }
    end   
end

r3 = ReportingSystem.new 
puts "#{rs.get_piano_desc} costs #{rs.get_piano_price.to_s.ljust(6.‘0‘)}"

# => Excellent piano costs 120.00

 

Ghost method: 

如果我们使用了不存在的method,会自动跳转到method_missing  method,不过method_missing 可以被复写:

class Mystery 
    #no_methods defined 
    def method_missing (method, *args)
        puts "Looking for..."
        puts "\"#{method}\" with params {#{args.join(‘,‘)}} ?"
        puts "Sorry... He is on vacation... "
        yield "Ended up in method_missing" if block_given?
    end
end 

m = Mystery.new 
m.solve_mystery("abc", 123123) do |answer|
    puts "And the answer is: #{answer}" 
end

# =>  Looking for...
# =>  "solve_mystery" with params (abc,123123) ?
# =>  Sorry... He is on vacation...
# =>  And the answer is: Ended up in method_missing

* method_missing gives you the power to "fake" the methods

* 这被叫做ghost methods 是因为 它并不真正意义上的存在

*ruby built-in classes use method_missing and dynamic methods all over the place... 

 

Struct and OpenStruct:

Struct: 特定类的生成器,每个类都被定义为保存一组变量及其访问器(动态
方法)

OpenStruct: 对象(类似于Struct),其属性在第一次分配时动态创建(“Ghost方法”)。

Customer = Struct.new(:name, :address) do #block is optional 
    def to_s 
        "#{name} lives at #{address}"
    end
end 
jim = Customer.new("Jim", "-1000 wall Street")
puts jim # => Jim lives at -1000 wall Street


require ostruct # => need to require ostruct for OpenStruct 

some_obj = OpenStruct.new(name: "Joe", age: 15)
some_obj.sure = "three"
some_obj.really = "yes, it is true" 
some_obj.not_only_strings = 10
puts "#{some_obj.name} #{some_obj.age} #{some_obj.really}"
#=> Joe 15 yes,it is true

method_missing and Performance:

因为调用是直接的,所以可能会慢一些,但大多数情况下不影响。

如果考虑响应速度的话,可以考虑hybird approach 

*Define a real method from inside method missing after an attempted ‘call’

 

Ghost methods allow you to call methods as if they are there even though they are not
Method behavior can be defined at runtime , for example based on database columns existing or not .

 

RoR - MetaProgramming

标签:tap   The   style   div   ghost   lin   temp   obj   rom   

原文地址:https://www.cnblogs.com/vixennn/p/10695260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!