2013-02-22 2 views

ответ

8

Посмотрите на sourcify драгоценный камне:

proc { x + y }.to_source 
# >> "proc { (x + y) }" 
+1

sourcify имеет большое предупреждение для чего-либо после Ruby 1.9. Мне повезло с камнем source_method для Ruby 2.1.2 (этот pry включает в себя зависимость, поэтому уже был доступен в нашей тестовой инфраструктуре, где мне это нужно). У меня есть подробный ответ здесь: http://stackoverflow.com/questions/1675053/printing-the-source-code-of-a-ruby-block/36654421#36654421 – Nick

5

ли Вы имеете в виду исходный кода или его байткод представление ?

Для первых, вы можете использовать стандартный метод Proc в source_location

p.source_location 
=> ["test.rb", 21] 

и прочитать соответствующие строки кода.

Для последнего это может пригодиться RubyVM :: InstructionSequence и его метод класса демонтирует:

irb> RubyVM::InstructionSequence.disasm p 
=> "== disasm: <RubyVM::InstructionSequence:block in [email protected](irb)> 
=====\n== catch table\n| catch type: redo st: 0000 ed: 0011 sp: 0000 
cont: 0000\n| catch type: next st: 0000 ed: 0011 sp: 0000 cont: 
0011\n|------------------------------------------------------------------------\n 
0000 trace   1            
( 1)\n0002 putself   \n0003 putstring  \"ok\"\n0005 
send    :puts, 1, nil, 8, <ic:0>\n0011 leave   \n" 
+1

'RubyVM' является нестандартным расширением YARV , Он не является частью спецификации языка Ruby. У МРТ этого нет, у Рубиния этого нет, у MagLev его нет, у JRuby его нет, у IronRuby его нет. Я бы предпочел не полагаться на то, что работает только на одной реализации Ruby. –

+0

@ JörgWMittag Итак, МРТ застряла на 1,8, а Ruby 1.9 не является официальной реализацией? –

+0

@ JörgWMittag С другой стороны, я вообще согласен не полагаться на конкретные функции реализации, но иногда их трудно сохранить. –

4

Нет, нет никакого способа, чтобы сделать это в Ruby.

Некоторые реализации Ruby могут иметь или не иметь специфические для реализации способы получения исходного кода.

Вы также можете попытаться использовать Proc#source_location, чтобы найти файл, который был определен в Proc, а затем проанализируйте этот файл, чтобы найти исходный код. Но это не будет работать, если Proc не был определен в файле (например, если он был задан динамически с помощью eval) или если исходный файл больше не существует, например. потому что вы используете AOT-скомпилированную версию вашей программы.

Итак, короткий ответ: нет, нет способа. Долгий ответ: есть некоторые способы, которые могут или не могут иногда работать в зависимости от слишком многих факторов, даже чтобы сделать эту работу надежно.

Это даже не учитывается Proc s, которые даже не имеют a исходный код Ruby, поскольку они были определены в собственном коде.

1

Если процедура определена в файл, U может получить файл расположение прока затем сериализовать его, то после десериализации использовать место, чтобы вернуться к технологич снова

proc_location_array = proc.source_location

после десериализации:

имя_файла = proc_location_array [0]

line_number = proc_location_array [1]

proc_line_code = IO.readlines (имя_файла) [line_number - 1]

proc_hash_string = proc_line_code [proc_line_code.index ("{") .. proc_line_code.длина]

прок = Eval ("лямбда # {proc_hash_string}")

Смежные вопросы