From 04272d1e3082dbb856b62daf0b11d50925dda612 Mon Sep 17 00:00:00 2001 From: Shamaoke Date: Fri, 30 Jan 2015 06:44:51 +0300 Subject: [PATCH 1/2] Add __FILE__, __LINE__ to class-, module_eval calls Sometimes when exploring or debugging code it's necessary to know where some method was defined. For this purpose `Method#source_location` is used. It reports a filename and a line in the file with a method definition. However, when using `Module#class_eval` and `Module#module_eval` to dynamically define methods, the output of `Method#source_location` is uninformative. For this reason it's better to add `__FILE__` and `__LINE__` constants as the second and third arguments to the aforementioned methods. This allows `Method#source_location` to properly locate methods which was defined dynamically. Here's some examples: require 'origin' class Band extend Origin::Forwardable select_with :queryable def self.queryable Object.new.extend Origin::Queryable end end Band.method(:where).source_location # without __FILE__, __LINE__ #=> ["(eval)", 1] # with __FILE__, __LINE__ #=> ["<...>/lib/origin/forwardable.rb", 53] require 'origin' module Finders extend Origin::Forwardable select_with :queryable def queryable Object.new.extend Origin::Queryable end end class Band extend Finders end Band.method(:where).source_location # without __FILE__, __LINE__ #=> ["(eval)", 1] # with __FILE__, __LINE__ #=> ["<...>/lib/origin/forwardable.rb", 47] --- lib/origin/forwardable.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/origin/forwardable.rb b/lib/origin/forwardable.rb index d1a6fcd..8749ecd 100644 --- a/lib/origin/forwardable.rb +++ b/lib/origin/forwardable.rb @@ -44,13 +44,13 @@ def select_with(receiver) # @since 1.0.0 def __forward__(name, receiver) if self.class == Module - module_eval <<-SEL + module_eval <<-SEL, __FILE__, __LINE__ def #{name}(*args, &block) #{receiver}.__send__(:#{name}, *args, &block) end SEL else - (class << self; self; end).class_eval <<-SEL + (class << self; self; end).class_eval <<-SEL, __FILE__, __LINE__ def #{name}(*args, &block) #{receiver}.__send__(:#{name}, *args, &block) end From c532cf85078cc3b48e1ed16f49dfb0fd36fba596 Mon Sep 17 00:00:00 2001 From: Shamaoke Date: Sat, 31 Jan 2015 06:11:39 +0300 Subject: [PATCH 2/2] Replace __LINE__ to __LINE__.succ The actual location of a method which was defined through `Module#class-/module_eval` with a heredoc as the first argument is one line below the one reported by `Method#source_location`. For that reason it needs to increase the __LINE__ value by one. --- lib/origin/forwardable.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/origin/forwardable.rb b/lib/origin/forwardable.rb index 8749ecd..9f65a6f 100644 --- a/lib/origin/forwardable.rb +++ b/lib/origin/forwardable.rb @@ -44,13 +44,13 @@ def select_with(receiver) # @since 1.0.0 def __forward__(name, receiver) if self.class == Module - module_eval <<-SEL, __FILE__, __LINE__ + module_eval <<-SEL, __FILE__, __LINE__.succ def #{name}(*args, &block) #{receiver}.__send__(:#{name}, *args, &block) end SEL else - (class << self; self; end).class_eval <<-SEL, __FILE__, __LINE__ + (class << self; self; end).class_eval <<-SEL, __FILE__, __LINE__.succ def #{name}(*args, &block) #{receiver}.__send__(:#{name}, *args, &block) end