RubyにはPythonのdisみたいなものはないのかなぁと言っていたら、ささださんに教えてもらった。
irb(main):017:0> def facto(n) irb(main):018:1> if n == 0 then 1 else facto(n - 1) * n end irb(main):019:1> end => nil irb(main):020:0> puts RubyVM::InstructionSequence.disasm(Object.method(:facto)) == disasm: <RubyVM::InstructionSequence:facto@(irb)>==================== local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1) [ 2] n<Arg> 0000 trace 8 ( 17) 0002 trace 1 ( 18) 0004 getlocal n 0006 putobject 0 0008 opt_eq <ic:4> 0010 branchunless 18 0012 trace 1 0014 putobject 1 0016 jump 37 0018 trace 1 0020 putnil 0021 getlocal n 0023 putobject 1 0025 opt_minus <ic:5> 0027 send :facto, 1, nil, 8, <ic:2> 0033 getlocal n 0035 opt_mult <ic:6> 0037 trace 16 ( 19) 0039 leave ( 18) => nil
Pythonだとこう
>>> import dis
>>> def facto(n):
... if n == 0:
... return 1
... else:
... return facto(n - 1) * n
...
>>> dis.dis(facto)
2 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (0)
6 COMPARE_OP 2 (==)
9 JUMP_IF_FALSE 5 (to 17)
12 POP_TOP
3 13 LOAD_CONST 2 (1)
16 RETURN_VALUE
>> 17 POP_TOP
5 18 LOAD_GLOBAL 0 (facto)
21 LOAD_FAST 0 (n)
24 LOAD_CONST 2 (1)
27 BINARY_SUBTRACT
28 CALL_FUNCTION 1
31 LOAD_FAST 0 (n)
34 BINARY_MULTIPLY
35 RETURN_VALUE
36 LOAD_CONST 0 (None)
39 RETURN_VALUE