< :the previous in number
^ :the list in numerical order
> :the next in number
P :the previous (in thread)
N :the next artilce (have the same parent)
|<:the top of this thread
>|:the next thread
^ :the parent (reply-to)
_:the child (an article replying to this)
>:the elder article having the same parent
<:the youger article having the same parent
---:split window and show thread lists
| :split window (vertically) and show thread lists
~ :close the thread frame
.:the index
..:the index of indices
dblack / wobblini.net wrote:
> Hi --
>
> On Wed, 6 Dec 2006, Martin DeMello wrote:
>
> > While golfing with the hex_ip thread, I realised that map takes no
> > argument, and join takes no block, leaving a vacuum for a combined
> > method:
>
> Your point about map re-raised a question that was in my head
> recently.
>
> There was an RCR a while back, rejected by Matz, that asked for:
>
> enum.map(:m)
>
> to be the same as:
>
> enum.map {|e| e.m }
>
> It looks like Ruby >= 1.9 has this:
>
> enum.map(&:m)
>
> which strikes me as the same thing, functionally, but visually noisier
> and semantically more obscure.
>
> I'm just wondering what the rationale is for rejecting the simple
> version and introducing the less simple one.
>
>
> David
Good question. One guess is that they wanted a more generic approach,
instead of manually handling specific methods. But that's a guess.
This may have been implemented before, but here's something I've been
toying with:
module Enumerable
# Returns the numeric total of the elements of +enum+.
# Raises an error if any of the elements are non-numeric.
#
def sum
total = 0
each{ |val| total += val }
total
end
# Returns a new array containing the results of running
# +block+ once for every element in the +enum+. Any symbols
# passed as arguments are assumed to be methods, and will be
# called on every element *before* being yielded to the block.
# Non-symbols are assumed to be arguments to those methods.
#
# Examples:
#
# array = ['foo', 'bar']
#
# array.map(:capitalize) => ['Foo', 'Bar']
# array.map(:+, 'x') => ['foox', 'barx']
# array.map(:+, 'y', :upcase) => ['FOOY', 'BARY']
#
def map(*args)
array = [] unless block_given?
hash = {}
key = nil
args.each{ |arg|
if arg.is_a?(Symbol)
key = arg
hash[key] = []
else
hash[key] << arg
end
}
each{ |obj|
hash.each{ |sym, args|
if args.empty?
obj = obj.send(sym)
else
obj = obj.send(sym, *args)
end
}
if block_given?
yield obj
else
array << obj
end
}
return array unless block_given?
end
end
class Array
# Returns a new array containing the results of running
# +block+ once for every element in the +enum+. Any symbols
# passed as arguments are assumed to be methods, and will be
# called on every element *before* being yielded to the block.
# Non-symbols are assumed to be arguments to those methods.
#
# Examples:
#
# array = ['foo', 'bar']
#
# array.map(:capitalize) => ['Foo', 'Bar']
# array.map(:+, 'x') => ['foox', 'barx']
# array.map(:+, 'y', +upcase) => ['FOOY', 'BARY']
#--
# The Array class actually has its own implementation of
# the +map+ method, hence the duplication.
#
def map(*args)
array = [] unless block_given?
hash = {}
key = nil
args.each{ |arg|
if arg.is_a?(Symbol)
key = arg
hash[key] = []
else
hash[key] << arg
end
}
each{ |obj|
hash.each{ |sym, args|
if args.empty?
obj = obj.send(sym)
else
obj = obj.send(sym, *args)
end
}
if block_given?
yield obj
else
array << obj
end
}
return array unless block_given?
end
end