Array map, concise notation

I often encounter the following pattern:

enum.map {|e| e.f} # /1/
enum.map {|e| f(e)} # /2/

For the first case, I can get rid of writing the parameter e explicitly,
by using

enum.map(&:f) # /1/

Is it possible to write the second way too in a form, where I don’t need
to introduce a name for the parameter ‘e’?

Ronald

module Enumerable
def smap(s)
map { |a| eval “#{s}(a)” }
end
end

def sqr(a) a*a end
p [1,2,3].smap(:sqr)

p [1,2,3].smap(“Math.log”)

Regis d’Aubarede wrote in post #1181686:

map { |a| eval "#{s}(a)" }

Aaarrgghhh!!!

Technically speaking, this indeed solved my question, but …

I think I should have make clear, that I was looking for a solution NOT
involving eval :wink:

Thanks anyway!

Ronald

Or with variable arguments to the function, although this is probably
overkill:

module Enumerable
def smap(f,scope=nil,pos=0,*args)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
a1 = args[0,pos]
a2 = args[pos…-1] || []
map{|a|m[*a1,a,*a2]}
end
end

def sqr(x)
x*x
end

def third(a,b,c,d,e)
c
end

p [1,2,3].smap(:sqr)

=> [1,4,9]

p [2,4].smap(:*,“xy”)

=> [“xyxy”,"xyxyxyxy]

p [1,2,3].smap(:log,Math)
p [10,100,1000].smap(:log,Math,0,10)
p [2,5].smap(:third,nil,2,0,0,0,0)
p [2,5].smap(:third,nil,1,0,0,0,0)

I agree that eval is to be avoided. How about:

module Enumerable
def smap(f,scope=nil)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
map{|a|m[a]}
end
end

def sqr(x)
x*x
end

p [1,2,3].smap(:sqr)

=> [1,4,9]

p [2,4].smap(:*,“xy”)

=> [“xyxy”,"xyxyxyxy]

p [1,2,3].smap(:log,Math)

Dansei Yuuki wrote in post #1181688:

module Enumerable
def smap(f,scope=nil)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
map{|a|m[a]}
end
end

Ingenious! This looks so useful, that it should go into the Ruby
core!

Ronald