To be clear, I recognize that eval
is evil, this is not for production code. That said, I'm trying to figure out if I can, for golfing purposes, shorten:
$*.map{eval _1}
any further, in much the same way that:
$*.map{|x|x.to_i}
# and
$*.map{_1.to_i}
can shorten to:
$*.map(&:to_i)
Python's first class functions make this easy; a listcomp like:
[eval(x)for x in sys.argv[1:]]
can shorten to:
[*map(eval,sys.argv[1:])]
because eval
is a first-class function, and without parentheses it isn't called. But I've tried everything I can think of to suppress eval
trying to run before being passed, e.g. $*.map(&eval)
, $*.map(:eval)
, and variations thereof, and it never works (because it calls eval
with no arguments, or passes something that does not act as the eval
function).
It's possible this can't be golfed, but I'm curious if there is any way, to get a direct reference to eval
(not create some new custom Proc
or lambda
or the like that happens to invoke it internally) that can be passed around as an argument?
(To be clear, this isn't an actual code golf challenge, so I believe it remains on-topic for StackOverflow; I happen to want to do this for golf, but being able to convert top-level functions to first-class objects to pass them around is useful in some cases outside of golfing)
eval
is a method in Kernel
like most of the other things in Ruby that are "methods that pretend to be functions" so you can use Object#method
to get a reference to it. Then use &
to to convert that Method
to a Proc
:
$*.map(&method(:eval))
So method(:eval)
is your "direct reference" to eval
. But you still have to call #to_proc
to get something that #map
will be happy with.
Maybe not really great for golf due to the length of method
but I can't think of anything else.