Cleaner syntax for .map (is there already a way, or ruby2 idea?)

T

Trans

David said:
I definitely *don't* want it to work :) I dislike using dot syntax
for non-dot semantics. I've never liked things like:

hash.where.the.key.equals(10)

even though they can usually be made to work.

I sort-of agree. It's definitely a semantic we're not used to --using a
method call to give us a "reoriented" version of the same thing --kind
of like having Roles. I suspect this will become a more common paradigm
over time and me may grow acustomed to it, but I'm with you in that I'd
rather have a distinguishing indication of when that's occuring.
Perhaps:

people:every.email_addr

And maybe that's what Matz already has in mind. And besides, it would
be nice to have it as a language feature becasue current
implementations are not very efficient:

def every
Functor.new do |op,*args|
self.collect{ |a| a.send(op,*args) }
end
end

or at best

def every
@__every_functor__ ||= Functor.new do |op,*args|
self.collect{ |a| a.send(op,*args) }
end
end
I continue to struggle to understand what people find so horrible
about ary.each {|item| .... }, ary.map {|item| ... }, and so forth.
I'll have some more coffee and maybe I'll start to see the light....

Not horrible, but looking at a language like R with it's elemewise
operations, one kind of wishes we had shorthands techinques as nice.

BTW, I have another version of #every which is even more R-like which
DeMello helped write. But I'm searching for a another name for it. Here
it is:

module Enumerable

# Returns an elementwise Functor designed to make R-like
# elementwise operations possible.
#
# [1,2].ew + 3 #=> [4,5]
# [1,2].ew + [4,5] #=> [5,7]
# [1,2].ew + [[4,5],3] #=> [[5,7],[4,5]]
#
#--
# Special thanks to Martin DeMello for helping to develop this.
#++
def elementwise
Functor.new do |op,*args|
a = args.collect do |arg|
if arg.kind_of?(Enumerable)
ln = ( arg.length > self.length ? self.length : arg.length )
self[0...ln].zip(arg[0...ln]).collect{ |a,b| a.send(op,b) }
#self[0...ln].zip(arg[0...1n]).collect{ |a,b| b ?
a.send(op,b) : nil }
else
self.collect{ |a| a.send(op,arg) }
end
end
a.flatten! if args.length == 1
a
end
end

alias_method :ew, :elementwise

end

Any suggestions?

T.
 
S

Simon Strandgaard

Maybe this can be useful?

--
Simon Strandgaard


class Array
def xmap(*symbols)
symbols.each do |symbol|
s =3D symbol.to_s
eval "def #{s}(*args);map{|i|i.send:)#{s}, *args)};end"
end
end
end


ary =3D %w(a b c d e)

ary.xmap:)upcase, :gsub)

p ary[0].upcase # "A"
p ary.upcase # ["A", "B", "C", "D", "E"]
p ary.gsub(/[bd]/, 'X') # ["a", "X", "c", "X", "e"]
 
M

Martin DeMello

Simon Strandgaard said:
ary = %w(a b c d e)

ary.xmap:)upcase, :gsub)

p ary[0].upcase # "A"
p ary.upcase # ["A", "B", "C", "D", "E"]
p ary.gsub(/[bd]/, 'X') # ["a", "X", "c", "X", "e"]

I don't like that one, because it provides no visual distinction between
methods that act on the array as a whole and methods that map over it.
Would be a nice place to introduce the -> operator, though :)

martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,184
Messages
2,570,979
Members
47,579
Latest member
CharaS3188

Latest Threads

Top