From: "Stefan Huettenrauch said:
Today I was looking for some (almost) scientific sources (pdf, articles,
...) that give an insight what really happens behind the scenes and that
explains the technical details of Ruby; how does Ruby actually work??
Unfortunately I only found language references, how to code guides and
alike. Nothing that states what is really happening with my piece of
code when I call 'ruby myfile.rb'
If you guys know some sources of such pdfs, books, articles, please let
me know.
Charles Thornton has been moving ahead with a Japanese -> English
translation of the Ruby Hackers Guide, which has many chapters focused
on the ruby internals. It is a work in progress, but the latest release is
here:
http://www.hawthorne-press.com/Release_Integrated_RHG_Dec_24_2007.tgz
Also, you may find the instruction sequence disassembler in ruby 1.9
useful. For example:
irb(main):001:0> RUBY_VERSION
=> "1.9.0"
irb(main):002:0> is = VM::InstructionSequence.compile('foo.bar = 42')
=> <ISeq:<compiled>@<compiled>>
irb(main):003:0> puts is.disasm
== disasm: <ISeq:<compiled>@<compiled>>=================================
0000 putnil ( 1)
0001 putnil
0002 send :foo, 0, nil, 24, <ic>
0008 putobject 42
0010 setn 2
0012 send :bar=, 1, nil, 0, <ic>
0018 pop
0019 leave
=> nil
This allows one to compile ruby expressions to YARV bytecode, and
disassemble the bytecode.
I think the 'send' at offset 0002 may be particularly interesting. I am
not myself familiar with the 1.9 VM instructions yet, but it appears the
send primitive is used both for local variable lookup, as well as sending
messages to objects. (Note that the same instruction sequence is
compiled regardless of whether any local variable named 'foo' actually
exists or not when the sequence is compiled... Thus it would seem
that even binding to local variables is completely dynamic in ruby.)
Rather than using the send primitive, there seem to be custom primitives
for global- and instance-variable lookup:
irb(main):008:0> is3 = VM::InstructionSequence.compile('$foo.bar = 42')
=> <ISeq:<compiled>@<compiled>>
irb(main):009:0> puts is3.disasm
== disasm: <ISeq:<compiled>@<compiled>>=================================
0000 putnil ( 1)
0001 getglobal $foo
0003 putobject 42
0005 setn 2
0007 send :bar=, 1, nil, 0, <ic>
0013 pop
0014 leave
=> nil
irb(main):010:0> is4 = VM::InstructionSequence.compile('@foo.bar = 42')
=> <ISeq:<compiled>@<compiled>>
irb(main):011:0> puts is4.disasm
== disasm: <ISeq:<compiled>@<compiled>>=================================
0000 putnil ( 1)
0001 getinstancevariable

foo
0003 putobject 42
0005 setn 2
0007 send :bar=, 1, nil, 0, <ic>
0013 pop
0014 leave
=> nil
Anyway, fun stuff.
Regards,
Bill