Drew
Drew

Reputation: 1777

How to pass a block

For the sake of simplicity, I've tried to abstract the problem down to its core elements. I've included a small piece of functionality wherein I use Socket to show that I want to pass the block further down into a method which is a black box for all intents and purposes. I'm also passing a constant True for the sake of showing I want to pass arguments as well as a yield block.

With all that being said, if I small have a hierarchy of calls as such:

def foo(use_local_source)
  if use_local_source
    Socket.unix("/var/run/my.sock") &yield
  else
    Socket.tcp("my.remote.com",1234) &yield
  end
end

foo(True) { |socket|
  name = socket.read
  puts "Hi #{name}, I'm from foo."
}

How can I pass the implicitly declared block right down through foo and into Socket as if I were calling Socket.tcp(...) { ... } directly.

I know I could set it as an argument, but it doesn't feel idiomatic to Ruby. Is this also untrue and I should pass it as an argument? I've tried combinations of & and *, and I get a range of exception.

Upvotes: 1

Views: 113

Answers (1)

Philip Hallstrom
Philip Hallstrom

Reputation: 19879

def foo(use_local_source)
  if use_local_source
    yield Socket.unix("/var/run/my.sock")
  else
    yield Socket.tcp("my.remote.com",1234)
  end
end

From the docs for yield:

Yields control back to the context that resumed the fiber, passing along any arguments that were passed to it.

Upvotes: 1

Related Questions