I was trying out refinements to see if they would help clean up some parsing code. I liked defining a couple of methods for the String class to respond to, but really didn’t want them as permanent monkey patches on String.
And so, I had a pipe mapping module with refinements:
module PipeMapping
refine String do
def only_lines_with_pipes
self.lines.select { |s| s =~ /\|/ }
end
def pipes_to_array
self.split('|').map(&:strip)
end
end
end
I added the following to my class to allow it to load itself:
using PipeMapping
def self.initalize_mappings
data_to_load.only_lines_with_pipes.map(&:pipes_to_array).each do |mapping|
# do stuff
end
end
I got the following output:
...in `map': super: no superclass method `pipes_to_array' for "A|B|C\n":String (NoMethodError)
The problem is that Symbol#to_proc
will end up operating outside of the scope of the refinement using
invocation, and will, therefore, have no knowledge of the method.
A quick change to a block works:
using PipeMapping
def self.initalize_mappings
data_to_load.only_lines_with_pipes.map{|s| s.pipes_to_array}.each do |mapping|
# do stuff
end
end
I’m still trying to decide if this is a satisfactory trade-off.