Skip to content

Instantly share code, notes, and snippets.

@ahoward
Last active May 15, 2016 11:45
Show Gist options
  • Select an option

  • Save ahoward/38d2dfb2657b857d9105bdc478c1df55 to your computer and use it in GitHub Desktop.

Select an option

Save ahoward/38d2dfb2657b857d9105bdc478c1df55 to your computer and use it in GitHub Desktop.
# Util.bcall(arg_1, arg_2, &callback)
module Util
def bcall(*args, &block)
call(block, :call, *args)
end
def call(object, method, *args, &block)
args = args_for_arity(args, object.method(method).arity)
object.send(method, *args, &block)
end
def args_for_arity(args, arity)
arity = Integer(arity.respond_to?(:arity) ? arity.arity : arity)
arity < 0 ? args.dup : args.slice(0, arity)
end
end
@npras
Copy link

npras commented May 15, 2016

@ahoward may I know what this does?

I initially thought it as a utility that can be used to call procs and lambdas via this common api where the lambda's argument strictness is bye-passed, like:

callback = Proc.new {|a,b| [a, b] }
callback = lambda {|a,b| a + b }

p Util.bcall(1, 2, 3, 4, &callback)  # I had to `extend self` the module to get this working. Is that how it's intended to be used?

I thought using it with a lambda will still succeed by only slicing first 2 args. But it failed in the default lambda's manner.

Also weird is this: you are checking if the arity variable responds to :arity (line#14). But the arity param variable comes from object.method(method).arity which will always be an integer value.
The only way the respond_to will return true is if, somehow, object.method(method).arity is actually a method!

But I can't see that happening in any case (except maybe by overriding Method#arity to return another method, but why would anybody do that?)

Please clarify.

Also I've now become your fan after hearing your rubyrogues podcast where you talk about the need for devs to do meaningful contribution. Loved it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment