Skip to content

Instantly share code, notes, and snippets.

@nilium
Created March 8, 2014 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nilium/9429363 to your computer and use it in GitHub Desktop.
Save nilium/9429363 to your computer and use it in GitHub Desktop.
Horrible hack to enable _s as placeholders in Ruby, similar to Scala.
# A horrible hack to enable _ as placeholders in Ruby, similar to block behavior
# in Scala.
#
# Obviously breaks if used across multiple threads, though probably in subtle
# ways. The break can be mitigated by instead wrapping the arguments in an
# instance of something and then doing instance_exec, where _ is a method on
# the instance, but this messes up the block's binding.
#
# There's probably a way around it all, but it's honestly not worth the trouble
# and the typing saved isn't worth the utter confusion anything like this would
# inevitably cause.
def __anon_method__(args)
if 1 == args.length
-> (n = nil) do
raise ArgumentError, "No defined argument" unless n.nil? || 0 == n
args[0]
end
else
counter = 0
-> (n = nil) do
if n.nil?
n = counter
counter += 1
end
raise ArgumentError, "No defined arguments" unless args.length > n && 0 <= n
args[n]
end
end
end
def __define_shift_arg__(args)
method = if Object.method_defined?(:_)
Object.instance_method(:_)
end
Object.__send__(:define_method, :_, __anon_method__(args))
if method
-> () { Object.__send__(:define_method, :_, method) }
else
-> () { Object.__send__(:remove_method, :_) }
end
end
def anon(obvious_block = nil, &block)
block ||= obvious_block
arity = block.arity
return block if arity < 0
-> (*args) do
cleanup = __define_shift_arg__(args)
begin
case arity
when 0 then block.call
else block.call(*(args.shift(arity)))
end
ensure
cleanup.call
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment