Ruby 元编程 代码块

178 篇文章 0 订阅




闭包

  1. 2.0.0p247 :133 >   def my_method  
  2. 2.0.0p247 :134?>     x="GoodBye"  
  3. 2.0.0p247 :135?>     yield("cruel")  
  4. 2.0.0p247 :136?>   end  
  5.  => nil   
  6. 2.0.0p247 :137 > x = "Hello"  
  7.  => "Hello"   
  8. 2.0.0p247 :138 > my_method {|y| "#{x}, #{y} world"}  
  9.  => "Hello, cruel world"   
  10. 2.0.0p247 :139 >   

作用域

块作用域   作用域门

  1. 2.0.0p247 :139 > v1 =1  
  2.  => 1   
  3. 2.0.0p247 :140 > class MyClass  
  4. 2.0.0p247 :141?>   v2 =2  
  5. 2.0.0p247 :142?>   local_variables  
  6. 2.0.0p247 :143?>   def my_method  
  7. 2.0.0p247 :144?>     v3 =3  
  8. 2.0.0p247 :145?>     local_variables  
  9. 2.0.0p247 :146?>     end  
  10. 2.0.0p247 :147?>   local_variables  
  11. 2.0.0p247 :148?>   end  
  12.  => [:v2]   
  13. 2.0.0p247 :149 > obj = MyClass.new  
  14.  => #<MyClass:0x007fdaea070450>   
  15. 2.0.0p247 :150 > obj.my_method  
  16.  => [:v3]   
  17. 2.0.0p247 :151 > obj.my_method  
  18.  => [:v3]   
  19. 2.0.0p247 :152 > local_variables  
  20.  => [:v1:x:p:obj:a, :_]   
  21. 2.0.0p247 :153 >       


扁平化作用域

  1. 2.0.0p247 :156 > MyClass = Class.new do  
  2. 2.0.0p247 :157 >     puts "#{my_var} in the class definition"  
  3. 2.0.0p247 :158?>   define_method :my_method do  
  4. 2.0.0p247 :159 >       puts "#{my_var} in the method"  
  5. 2.0.0p247 :160?>     end  
  6. 2.0.0p247 :161?>   end  
  7. Success in the class definition  
  8. (irb):156: warning: already initialized constant MyClass  
  9. (irb):9: warning: previous definition of MyClass was here  
  10.  => MyClass   
  11. 2.0.0p247 :162 > MyClass.new.my_method  
  12. Success in the method  
  13.  => nil   
  14. 2.0.0p247 :163 >   

共享作用域
  1. 2.0.0p247 :178 >   def define_methods  
  2. 2.0.0p247 :179?>   shared = 0   
  3. 2.0.0p247 :180?>   Kernel.send :define_method:course do  
  4. 2.0.0p247 :181 >       shared  
  5. 2.0.0p247 :182?>     end  
  6. 2.0.0p247 :183?>   Kernel.send :define_method:inc do |x|  
  7. 2.0.0p247 :184 >       shared += x  
  8. 2.0.0p247 :185?>     end  
  9. 2.0.0p247 :186?>   end  

obj.instance_eval
  1. 2.0.0p247 :193 > class MyClass  
  2. 2.0.0p247 :194?>   def initialize  
  3. 2.0.0p247 :195?>     @v = 1  
  4. 2.0.0p247 :196?>     end  
  5. 2.0.0p247 :197?>   end  
  6.  => nil   
  7. 2.0.0p247 :198 > obj = MyClass.new  
  8.  => #<MyClass:0x007fdaea99f620 @v=1>   
  9. 2.0.0p247 :199 > obj.instance_eval do  
  10. 2.0.0p247 :200 >     self  
  11. 2.0.0p247 :201?>   @v  
  12. 2.0.0p247 :202?>   end  
  13.  => 1   
  14. 2.0.0p247 :203 > v = 2  
  15.  => 2   
  16. 2.0.0p247 :204 > obj.instance_eval {@v = v}  
  17.  => 2   
  18. 2.0.0p247 :205 > obj.instance_eval {@v}  
  19.  => 2   
  20. 2.0.0p247 :206 >   

C.new.instance_exec(3)
  1. 2.0.0p247 :206 > class C  
  2. 2.0.0p247 :207?>   def initialize  
  3. 2.0.0p247 :208?>     @x,@y = 1,2  
  4. 2.0.0p247 :209?>     end  
  5. 2.0.0p247 :210?>   end  
  6.  => nil   
  7. 2.0.0p247 :211 > C.new.instance_exec(3) {|arg| (@x + @y) * arg}  
  8.  => 9   
  9. 2.0.0p247 :212 >   


净结室

  1. 2.0.0p247 :215 > class CleanRoom  
  2. 2.0.0p247 :216?>   def complex_calculation  
  3. 2.0.0p247 :217?>     p 'complex_calculation'  
  4. 2.0.0p247 :218?>     end  
  5. 2.0.0p247 :219?>   def  
  6. 2.0.0p247 :220 >       do_something  
  7. 2.0.0p247 :221?>     end  
  8. 2.0.0p247 :222?>   end  
  9.  => nil   
  10. 2.0.0p247 :223 > clean = CleanRoom.new  
  11.  => #<CleanRoom:0x007fdaea8d5618>   
  12. 2.0.0p247 :224 > clean.instance_eval do  
  13. 2.0.0p247 :225 >     if complex_calculation > 10  
  14. 2.0.0p247 :226?>      do_something  
  15. 2.0.0p247 :227?>     end  
  16. 2.0.0p247 :228?>   end  


可调用对象

  1. 2.0.0p247 :235 > inc = Proc.new {|x|  x*2}  
  2.  => #<Proc:0x007fdaec009a00@(irb):235>   
  3. 2.0.0p247 :236 > inc.call(2)  
  4.  => 4   
  5. 2.0.0p247 :237 >   
  6. 2.0.0p247 :238 >   dec = lambda {|x| x-1}  
  7.  => #<Proc:0x007fdaea883728@(irb):238 (lambda)>   
  8. 2.0.0p247 :239 > dec.class  
  9.  => Proc   
  10. 2.0.0p247 :240 > dec.call(2)  
  11.  => 1   
  12. 2.0.0p247 :241 >   

&操作符
  1. 2.0.0p247 :242 >   def math(a,b)  
  2. 2.0.0p247 :243?>    yield(a,b)  
  3. 2.0.0p247 :244?>   end  
  4.  => nil   
  5. 2.0.0p247 :245 >  def teach_math(a,b,&operation)  
  6. 2.0.0p247 :246?>   puts "Let's do the math:"  
  7. 2.0.0p247 :247?>   puts math(a,b,&operation)  
  8. 2.0.0p247 :248?>   end  
  9.  => nil   
  10. 2.0.0p247 :249 > teach_math(3,4){|x,y| x * y}  
  11. Let's do the math:  
  12. 12  
  13.  => nil   
  14. 2.0.0p247 :250 >   

  1. 2.0.0p247 :251 >   def my_method(&the_proc)  
  2. 2.0.0p247 :252?>      the_proc  
  3. 2.0.0p247 :253?>   end  
  4.  => nil   
  5. 2.0.0p247 :254 > p = my_method{ |name| "Hello, #{name}"}  
  6.  => #<Proc:0x007fdaea048fb8@(irb):254>   
  7. 2.0.0p247 :255 > p.class  
  8.  => Proc   
  9. 2.0.0p247 :256 > p.call("BIll")  
  10.  => "Hello, BIll"   
  11. 2.0.0p247 :257 >   

  1. 2.0.0p247 :262 > my_proc = proc{"Bill"}  
  2.  => #<Proc:0x007fdaeaadf5f8@(irb):262>   
  3. 2.0.0p247 :263 > my_method("hello",&my_proc)  
  4. hello the , Bill  
  5.  => nil   
  6. 2.0.0p247 :264 >   


proc 和 lambda 对比  一般优先使用 lambda

  1. 2.0.0p247 :274 >   def double(obj)  
  2. 2.0.0p247 :275?>     obj.call * 2  
  3. 2.0.0p247 :276?>   end  
  4.  => nil   
  5. 2.0.0p247 :277 >  l = lambda { return 10 }  
  6.  => #<Proc:0x007fdaeaa257c0@(irb):277 (lambda)>   
  7. 2.0.0p247 :278 >  double(l)  
  8.  => 20   
  9. 2.0.0p247 :279 >   
  10. 2.0.0p247 :280 >   def another_dou  
  11. 2.0.0p247 :281?>    p = Proc.new { return 10}  
  12. 2.0.0p247 :282?>    result = p.call  
  13. 2.0.0p247 :283?>    return result * 2  
  14. 2.0.0p247 :284?>   end  
  15.  => nil   
  16. 2.0.0p247 :285 >   another_dou  
  17.  => 10   
  18. 2.0.0p247 :286 >   
  1. 同样效果在 Ruby 1.9 中之后  
  1. 2.0.0p247 :288 >   p = -> { x + 1 }  
  2.  => #<Proc:0x007fdaea9f6da8@(irb):288 (lambda)>   
  3. 2.0.0p247 :289 >  p2 = lambda {|x| x + 1}  
  4.  => #<Proc:0x007fdaea9e5f80@(irb):289 (lambda)>   
  5. 2.0.0p247 :290 >   


重访方法

  1. 2.0.0p247 :304 >  obj = MyClass.new(1)  
  2.  => #<MyClass:0x007fdaea99d4d8 @x=1>   
  3. 2.0.0p247 :305 >  m = obj.method :my_method  
  4.  => #<Method: MyClass#my_method>   
  5. 2.0.0p247 :306 >  m.call  
  6.  => 1   
  7. 2.0.0p247 :307 >   
  8. 2.0.0p247 :308 >     
  9. 2.0.0p247 :309 >   unbound = m.unbind  
  10.  => #<UnboundMethod: MyClass#my_method>   
  11. 2.0.0p247 :310 >   ano = MyClass.new(2)  
  12.  => #<MyClass:0x007fdaea966078 @x=2>   
  13. 2.0.0p247 :311 >  m = unbound.bind(ano)  
  14.  => #<Method: MyClass#my_method>   
  15. 2.0.0p247 :312 > m.call  
  16.  => 2   
  17. 2.0.0p247 :313 >  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值