ruby 的yield和block研究

继续研究ruby元编程那本书。对yield和block机制不是很了解,自己找了个小代码片段。请来反汇编工具分析出来,原来如此。

wu=%w(a b c)
p wu


def foo
 yield [1,2,3]
 yield 1
end
foo{|v| p v}

下面是反汇编

ruby --dump insns yield1.rb >yield1.txt

== disasm: <RubyVM::InstructionSequence:<main>@yield1.rb>===============
== catch table
| catch type: break  st: 0035 ed: 0038 sp: 0000 cont: 0038
|------------------------------------------------------------------------
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] wu         
0000 trace            1                                               (   1)
0002 putstring        "a"
0004 putstring        "b"
0006 putstring        "c"
0008 newarray         3
0010 setlocal_OP__WC__0 2
0012 trace            1                                               (   2)
0014 putself          
0015 getlocal_OP__WC__0 2
0017 opt_send_without_block <callinfo!mid:p, argc:1, FCALL|ARGS_SIMPLE>
0019 pop              
0020 trace            1                                               (   4)
0022 putspecialobject 1
0024 putspecialobject 2
0026 putobject        :foo
0028 putiseq          foo
0030 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0032 pop              
0033 trace            1                                               (   8)
0035 putself          
0036 send             <callinfo!mid:foo, argc:0, block:block in <main>, FCALL>
0038 leave            
== disasm: <RubyVM::InstructionSequence:foo@yield1.rb>==================
0000 trace            8                                               (   4)
0002 trace            1                                               (   5)
0004 duparray         [1, 2, 3]
0006 invokeblock      <callinfo!argc:1, ARGS_SIMPLE>
0008 pop              
0009 trace            1                                               (   6)
0011 putobject_OP_INT2FIX_O_1_C_ 
0012 invokeblock      <callinfo!argc:1, ARGS_SIMPLE>
0014 trace            16                                              (   7)
0016 leave                                                            (   6)
== disasm: <RubyVM::InstructionSequence:block in <main>@yield1.rb>======
== catch table
| catch type: redo   st: 0002 ed: 0009 sp: 0000 cont: 0002
| catch type: next   st: 0002 ed: 0009 sp: 0000 cont: 0009
|------------------------------------------------------------------------
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] v<Arg>     
0000 trace            256                                             (   8)
0002 trace            1
0004 putself          
0005 getlocal_OP__WC__0 2
0007 opt_send_without_block <callinfo!mid:p, argc:1, FCALL|ARGS_SIMPLE>
0009 trace            512
0011 leave            


可以看到所有的秘密:yield对应指令invokeblock,就是普通的回调而已。ruby的所以的元编程技巧都可以用汇编代码看到它的实现原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值