class Pry::Method::Patcher
def self.code_for(filename)
def self.code_for(filename) @@source_cache[filename] end
def cache_key
def cache_key "pry-redefined(0x#{method.owner.object_id.to_s(16)}##{method.name})" end
def definition_for_owner(line)
-
(String)
- The new definition line. e.g. def foo(bar, baz=1)
Parameters:
-
line
(String
) -- The original definition line. e.g. def self.foo(bar, baz=1)
def definition_for_owner(line) if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/ "def #{method.original_name}#{$'}" else raise CommandError, "Could not find original `def #{method.original_name}` line " \ "to patch." end end
def initialize(method)
def initialize(method) @method = method end
def patch_in_ram(source)
def patch_in_ram(source) if method.alias? with_method_transaction do redefine source end else redefine source end end
def redefine(source)
def redefine(source) @@source_cache[cache_key] = source TOPLEVEL_BINDING.eval wrap(source), cache_key end
def with_method_transaction
continue to work.
translation we make that not happen, which means that alias_method_chains, etc.
unaliased name (so that super continues to work). By wrapping that code in a
When we're redefining aliased methods we will overwrite the method at the
Run some code ensuring that at the end target#meth_name will not have changed.
def with_method_transaction temp_name = "__pry_#{method.original_name}__" method = self.method method.owner.class_eval do alias_method temp_name, method.original_name yield alias_method method.name, method.original_name alias_method method.original_name, temp_name end ensure begin method.send(:remove_method, temp_name) rescue StandardError nil end end
def wrap(source)
-
(String)
- The wrapped source.
Parameters:
-
source
(String
) --
def wrap(source) wrap_for_nesting(wrap_for_owner(source)) end
def wrap_for_nesting(source)
-
(String)
-
Parameters:
-
source
(String
) -- The source to wrap.
def wrap_for_nesting(source) nesting = Pry::Code.from_file(method.source_file).nesting_at(method.source_line) (nesting + [source] + nesting.map { "end" } + [""]).join(";") rescue Pry::Indent::UnparseableNestingError source end
def wrap_for_owner(source)
-
(String)
-
Parameters:
-
source
(String
) -- The source to wrap
def wrap_for_owner(source) Pry.current[:pry_owner] = method.owner owner_source = definition_for_owner(source) visibility_fix = "#{method.visibility} #{method.name.to_sym.inspect}" "Pry.current[:pry_owner].class_eval do; #{owner_source}\n#{visibility_fix}\nend" end