2011-12-29 2 views
1

, вдохновленный некоторой волной магии runtime edit sourcecode,Как получить исходный текст в рубине?

Я хочу сделать это в рубине. похоже, я не могу получить исходный код из метода/класса, есть ли способ сделать это?

Я пишу образец исходников, здесь:

def helloworld n 
    "hello #{n}" 
end 

o = Kernel.method :helloword 

Kernel.define_singleton_method o.name do |n| 
    eval o.source_code.sub('hello', 'hello world') 
end 

helloworld 'halida' #=> 'hello world halida' 
+0

Смотрите аналогичные вопросы по Stackoverflow: http://stackoverflow.com/questions/4740684/ruby-get-source-code или http://stackoverflow.com/questions/3393096/how -can-i-get-source-code-of-the-methods-dynamic-and-also-which-file-is-this-m или http://stackoverflow.com/questions/4719649/ruby-print-source -код или http://stackoverflow.com/questions/1164903/find-the-source-of-eval-code ... – mliebelt

ответ

0

Вы не можете получить строковое представление части кода, редактировать его и ожидать, что рубин переоценивать свои изменения. Единственный способ сделать что-то рядом с тем, что вы хотите, - это использовать , чтобы получить s-выражения источника, отредактировать и использовать Ruby2Ruby для генерации строки кода ruby. Их добавьте def ... и end в строку и вызовите eval вместе с ней.

Это слишком сложно и подвержено ошибкам, чтобы быть полезным в реальной ситуации. Но я не знаю другого пути.

Примечание: ParseTree работает только с Ruby 1.8.

+0

Хорошо, я буду использовать lisp для создания такого рода магии. – linjunhalida

+0

Вы абсолютно можете получить строковое представление исходного кода. Просто используйте '.method.source' для методов класса или' .instance_method.source' для методов экземпляра. Если вы хотите отредактировать строку и повторно применить ее, вы можете просто открыть класс переопределить метод и использовать 'eval' в новой строке. –

+0

См. Также 'class_eval' и' instance_eval' –

0

Посмотрите на method_source драгоценный камень. Используется командой pry REPL для команды show-method.

Похоже, что этот драгоценный камень использует стандарт Method#source_location (доступен в Ruby 1.9), чтобы найти способ и получить его исходный код. Очевидно, что это не работает для динамически определенных методов и методов С. Дополнительную информацию см. В документах.

0

Вы можете легко получить исходный код метода в Ruby.

Представьте себе следующую гипотетическую класс:

class Klass 
    def self.foo 
    :foo 
    end 

    def bar 
    :bar 
    end 
end 

Как вы можете видеть, этот класс имеет два метода:

  • метод класса .foo
  • метод экземпляра #bar

Использовать .method и .instance_method для доступа к программе матический:

m1 = Klass.method :foo 
=> #<Method: Klass.foo> 

m2 = Klass.instance_method :bar 
=> #<UnboundMethod: Klass#bar> 

Вы можете использовать метод .source, чтобы просмотреть их исходный код:

puts m1.source 
    def self.foo 
    :foo 
    end 
=> nil 

puts m2.source 
    def self.bar 
    :bar 
    end 
=> nil 

Поскольку рубин есть открытые классы и динамические нагрузки, вы можете также добавить или методов изменения во время выполнения. Просто повторно открыть класс и переопределить метод:

Klass.foo 
=> :foo 

class Klass 
    def self.foo 
    :foobar 
    end 
end 

Klass.foo 
=> :footer 

Другие методы, определенные ранее в классе останется неизменным:

Klass.bar 
=> :bar 

ПРЕДУПРЕЖДЕНИЕ: поведение класса переосмысление во время выполнения (также называемый " Monkey Patching ") - очень мощный инструмент, он также может быть несколько опасным. Текущие версии Ruby поддерживают гораздо более контролируемый способ обойти это под названием «уточнения».

Вы можете learn more about using refinements here