p = Proc.new{ puts 'ok' }
Можно ли увидеть код ruby в proc?Возможно ли увидеть код ruby в proc?
inspect
возвращает ячейку памяти:
puts p.inspect
#<Proc:[email protected](irb):2>
рубин 1.9.3
p = Proc.new{ puts 'ok' }
Можно ли увидеть код ruby в proc?Возможно ли увидеть код ruby в proc?
inspect
возвращает ячейку памяти:
puts p.inspect
#<Proc:[email protected](irb):2>
рубин 1.9.3
Посмотрите на sourcify драгоценный камне:
proc { x + y }.to_source
# >> "proc { (x + y) }"
ли Вы имеете в виду исходный кода или его байткод представление ?
Для первых, вы можете использовать стандартный метод 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"
'RubyVM' является нестандартным расширением YARV , Он не является частью спецификации языка Ruby. У МРТ этого нет, у Рубиния этого нет, у MagLev его нет, у JRuby его нет, у IronRuby его нет. Я бы предпочел не полагаться на то, что работает только на одной реализации Ruby. –
@ JörgWMittag Итак, МРТ застряла на 1,8, а Ruby 1.9 не является официальной реализацией? –
@ JörgWMittag С другой стороны, я вообще согласен не полагаться на конкретные функции реализации, но иногда их трудно сохранить. –
Нет, нет никакого способа, чтобы сделать это в Ruby.
Некоторые реализации Ruby могут иметь или не иметь специфические для реализации способы получения исходного кода.
Вы также можете попытаться использовать Proc#source_location
, чтобы найти файл, который был определен в Proc
, а затем проанализируйте этот файл, чтобы найти исходный код. Но это не будет работать, если Proc
не был определен в файле (например, если он был задан динамически с помощью eval
) или если исходный файл больше не существует, например. потому что вы используете AOT-скомпилированную версию вашей программы.
Итак, короткий ответ: нет, нет способа. Долгий ответ: есть некоторые способы, которые могут или не могут иногда работать в зависимости от слишком многих факторов, даже чтобы сделать эту работу надежно.
Это даже не учитывается Proc
s, которые даже не имеют a исходный код Ruby, поскольку они были определены в собственном коде.
Если процедура определена в файл, 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}")
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