Видя под капотом Руби? - PullRequest
3 голосов
/ 20 декабря 2011

Я недавно пробирался через прагматику языка программирования, 3-е издание, чтобы узнать больше о том, как работают языки, и я многому научился, глядя на сборку, созданную действительно базовым C-компилированным кодом GCC.,Я начинаю чувствовать себя более комфортно со статическими языками из семейства C, и я хотел бы начать изучать и интерпретируемые языки.

Ruby, мой любимый язык сценариев, был бы отличным кандидатом на это.,Я думаю, что было бы хорошо начать с МРТ в учебных целях и выяснить, как именно все сканирование / синтаксический анализ / семантический анализ / связывание / определение области видимости и другие виды магии происходят за кулисами.

Описано ли этоподробно где-нибудь, или есть ли какой-нибудь способ для меня, чтобы копаться в этом, как, скажем, с разборкой скомпилированной программы?Я не слишком много копался в интерпретируемых языках, поэтому я не знаю, с чего начать, если речь идет о МРТ.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 20 декабря 2011

Вы можете посмотреть байт-код YARV любого бита исходного кода Ruby с помощью RubyVM::InstructionSequence

Вот краткий пример:

class Greeter
  def initialize(name)
    @name = name
  end
  def greet!
    puts @name
  end
end

Greeter.new("Charlie").greet!

Затем вы можете скомпилировать и разобрать:

puts RubyVM::InstructionSequence.compile(src).disassemble

И получите вывод наподобие этого:

== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putspecialobject 3
0004 putnil           
0005 defineclass      :Greeter, <class:Greeter>, 3
0009 pop              
0010 trace            1                                               (  10)
0012 getinlinecache   19, <ic:0>
0015 getconstant      :Greeter
0017 setinlinecache   <ic:0>
0019 putstring        "Charlie"
0021 send             :new, 1, nil, 0, <ic:1>
0027 send             :greet!, 0, nil, 0, <ic:2>
0033 leave            
== disasm: <RubyVM::InstructionSequence:<class:Greeter>@<compiled>>=====
0000 trace            2                                               (   1)
0002 trace            1                                               (   2)
0004 putspecialobject 1
0006 putspecialobject 2
0008 putobject        :initialize
0010 putiseq          initialize
0012 send             :"core#define_method", 3, nil, 0, <ic:0>
0018 pop              
0019 trace            1                                               (   5)
0021 putspecialobject 1
0023 putspecialobject 2
0025 putobject        :greet!
0027 putiseq          greet!
0029 send             :"core#define_method", 3, nil, 0, <ic:1>
0035 trace            4                                               (   8)
0037 leave                                                            (   5)
== disasm: <RubyVM::InstructionSequence:initialize@<compiled>>==========
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] name<Arg>  
0000 trace            8                                               (   2)
0002 trace            1                                               (   3)
0004 getlocal         name
0006 dup              
0007 setinstancevariable :@name, <ic:0>
0010 trace            16                                              (   4)
0012 leave                                                            (   3)
== disasm: <RubyVM::InstructionSequence:greet!@<compiled>>==============
0000 trace            8                                               (   5)
0002 trace            1                                               (   6)
0004 putnil           
0005 getinstancevariable :@name, <ic:0>
0008 send             :puts, 1, nil, 8, <ic:1>
0014 trace            16                                              (   7)
0016 leave                                                            (   6)
2 голосов
/ 20 декабря 2011

Сам Ruby написан на C, так что, возможно, стоит взглянуть на код.https://github.com/ruby/ruby

Я также рекомендую статью Патрика Фарли об отправке метода.http://www.klankboomklang.com/2007/09/14/method-dispatch/

1 голос
/ 20 декабря 2011

Существует японская книга , которая описывает внутреннюю работу MRI 1.7.3, называемую Ruby Hacking Guide. Возможен частичный перевод на английский .

Несмотря на то, что перевод не завершен, и книга была основана на более старой версии ruby, я все же считаю ее превосходным ресурсом. Многие вещи, описанные в книге, вероятно, все еще актуальны в текущих версиях ruby, такие как структура объектов, как хранятся переменные экземпляра, как выполняется поиск метода и т. Д.

Это очень интересное чтение. Вы должны остерегаться различий между версиями, хотя. Всегда держите исходный код ruby ​​ под рукой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...