Hi --
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map
![Smile :) :)](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
*, 2) ?
Does the version currently in Ruby 1.9 support arguments?
I don't think so. I'm actually not sure where they'd go, since &:meth
is the block and not an argument.
David
A few days ago, I modified Dr. Nic's MapByMethod gem (locally) to
attempt to handle arguments. The results were interesting.
Scroll down for some examples.
#
# --copy into irb--
#
module FindByMethod
def method_missing method, *args, &block
begin
method_missing_handler method, *args, &block
rescue
super
end
end
FIND_BY_REGEX = /^(all|any|collect|detect|find_all|find|
first_match|grep|group_by|map|none|partition|reject|select|sort_by)_?
(by|where)?_([\w_]+\??)$/
QUERY_ITERATORS = ["all","any","none"]
def method_missing_handler method, *args, &block
unless method.to_s.match FIND_BY_REGEX
raise NoMethodError
end
iterator = $1
selector = $2
callmethod = $3
iterator += "?" if QUERY_ITERATORS.include? iterator
self.send(iterator) do |item|
if selector == "where"
# Arguments used in boolean comparison
if args.length == 1
args.first == item.send(callmethod)
else
args.include? item.send(callmethod)
end
else
# Arguments fall through
item.send(callmethod,*args)
end
end
end
end
Array.send :include, FindByMethod
#
# ---stop---
#
#
# Examples!
#
[1,2,3].map_by_succ
# => [2, 3, 4]
# -- equivalent to [1,2,3].map { |x| x.succ }
[1,2,nil].select_by_nil?
# => [nil]
# -- equivalent to [1,2,nil].select { |x| x.nil? }
#
# Now lets try some arguments.
# (Normally they're passed right to the method.)
#
[2,4,6].map_by_div(2)
# => [1, 2, 3]
["1","one"].select_by_match(/\d/)
# => ["1"]
#
# If you've gotten ahead of me, you're probably wondering
# how you would pull off a rails-like magic finder:
#
# users.find_by_name("charlie")
#
# I struggled with that one for a long time, before settling
# on using 'find_where' instead of 'find_by' where you need
# it to equal an argument rather than pass through an argument.
#
[1,2,'a'].select_where_class(Fixnum)
# => [1, 2]
# -- equivalent to [1,2,'a'].select { |x| x.class == Fixnum }
#
# You can use most enumerable methods as well.
#
[1,2,3].partition_where_to_f(3.0)
# => [[3], [1, 2]]
#
# Some special cases though are .any?, .none?, and .all?
#
#They work, but you need to omit the question mark or ruby
# throws up all over her prom dress.
#
[1,2,3].any_by_nil?
# => false
#
# Keep in mind that it's easy to mix up 'where' and 'by'.
# Compare these two identical sounding method calls.
#
[1,2,'a'].select_where_kind_of?(Fixnum)
[1,2,'a'].select_by_kind_of?(Fixnum)
# Can you guess which works and which crashes?
#
# _by_ works as it translates into:
# x.kind_of?(Fixnum)
#
#_where_ raises an exception because it becomes gibberish:
# x.kind_of? == Fixnum
#
# I had to run it to figure out the difference too. There's something
# seriously wrong with the words I chose to distinguish between
# passing an argument from equaling an argument.
#
# - Mike