facets
facets copied to clipboard
Array#to_proc
The method converts an associative array to a Proc which calls chain of methods on a given object. I use it mostly with enums in irb and specs as a shorthand to quickly make some actions on items.
[:to_i, :next, [:*, 2]].to_proc.call("2")
# => 6
chain = [[:[], 1], [:is_a?, String]]
chain.to_proc
the_hash = { one: "One", two: "Two", three: 3, four: nil }
the_hash.select(&chain)
# => { :one => "One", :two => "Two" }
mapping = { "one" => "1", "two" => "2", "" => "0" }
the_hash.values.map(&[:to_s, :downcase, [:sub, /one|two|$^/, mapping]])
# => ["1", "2", "3", "0"]
FYI another way to achieve the same result is via the its-it gem:
require 'its-it'
the_hash = { one: "One", two: "Two", three: 3, four: nil }
the_hash.select &it[1].is_a? String
# => { :one => "One", :two => "Two" }
mapping = { "one" => "1", "two" => "2", "" => "0" }
the_hash.values.map &it.to_s.downcase.sub(/one|two|$^/, mapping)
# => ["1", "2", "3", "0"]
(Disclaimer: I'm the author of the its-it gem, though the original idea wasn't mine.)
I like this it/its approach. I wonder, though, could it just be a method on Enumerator? e.g.
the_hash.values.map.it.to_s.downcase.sub(/one|two|$^/, mapping)
@trans interesting idea. I think something could be made on Enumerator, but I think it'd need a special method to tell it to end queuing the methods and execute the chain. Such as:
the_hash.values.map.it.to_s.downcase.sub(/one|two|$^/, mapping).do_it
which would mean that :do_it
wouldn't be available as a method on the object in the chain.
Also, consider
the_hash.values.map(&it.to_s.downcase.sub(/one|two|$^/, mapping)).sort
Using the Enumerator method approach that'd need to be something like
the_hash.values.map.it.to_s.downcase.sub(/one|two|$^/, mapping).do_it.sort
I'm not sure if that's clearer to read...?
I was thinking about going ahead and adding this a standard library (rather than a core library). That way it will be available, but you just have to require it separate. We can think about possible improvement later.
However, I just checked to code and it seems to have the wrong test. Why is it testing Array#only?