Callbacks in ruby

Hi everyone,

I've been struggling with something for a while and was hoping someone who
knows more about me than this would be able to help. I have this gist:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67. I'm
attempting to build in generic callbacks that I can port into a number of
our gems here (this is not an invitation for a discussion on the merits of
callbacks).

I've got them working nicely for before and after callbacks. My issue comes
with around callbacks. I can get them to work if I explicitly look for a
block argument and call it (as in this line:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67#file-main-rb-L30)
but I can't get it to work if I yield (as in this line:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67#file-main-rb-L35
).

No matter how much I mess with it I can't get it working. The thing is, I
know this is a solvable problem because Rails does this in this file:
https://github.com/rails/rails/blame/master/activesupport/lib/active_support/callbacks.rb,
so there has to be a way. Unfortunately, I can't seem to replicate their
approach.

Help?

···

--
*Kevin D. Deisz*
Localytics Software Engineer

Note that this doesn't work:

irb(main)> a = lambda { puts "yielding"; yield }
=> #<Proc:0x007ff421b4e408@(irb):13 (lambda)>

irb(main)> a.call { puts "hello" }
yielding
LocalJumpError: no block given (yield)
from (irb):13:in `block in irb_binding'
from (irb):15
from /usr/local/google/home/mdemello/.rbenv/versions/2.3.1/bin/irb:11:in
`<main>'

i.e. the block passed to Proc#call does not get passed to the lambda itself.

martin

···

On Wed, Sep 21, 2016 at 11:42 AM, Kevin Deisz <kevin.deisz@gmail.com> wrote:

Hi everyone,

I've been struggling with something for a while and was hoping someone who
knows more about me than this would be able to help. I have this gist:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67\. I'm
attempting to build in generic callbacks that I can port into a number of
our gems here (this is not an invitation for a discussion on the merits of
callbacks).

I've got them working nicely for before and after callbacks. My issue
comes with around callbacks. I can get them to work if I explicitly look
for a block argument and call it (as in this line:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf
67#file-main-rb-L30) but I can't get it to work if I yield (as in this
line: https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf
67#file-main-rb-L35).

No matter how much I mess with it I can't get it working. The thing is, I
know this is a solvable problem because Rails does this in this file:
https://github.com/rails/rails/blame/master/activesupport/lib/active_
support/callbacks.rb, so there has to be a way. Unfortunately, I can't
seem to replicate their approach.

Help?

--
*Kevin D. Deisz*
Localytics Software Engineer

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hi,

I've got them working nicely for before and after callbacks. My issue
comes with around callbacks.

> # still working
> chain.around { |target, &block| puts 'abefore'; block.call; puts 'aafter' }

> # boom - in `block in <main>': no block given (yield) (LocalJumpError)
> chain.around { puts 'aabefore'; yield; puts 'aaafter' }

Both codes pass the block "{...}" to the method, "chain.around".

In the working case, the block accept parameter "block" as
a Proc object, then call it in it as "block.call".

In the later case, the block tries to call a block given to the block, Since it's not given, ruby showed the message, 'no block given'.
We can use yield in a method to call a bock given to the method.

Toshi

···

On 2016/09/22 3:42, Kevin Deisz wrote:

I think I did something like this a long time ago. You'll probably
find it still in the archives. Actually it is so long ago, I don't
remember the details but I do remember that there was before, after
and around code. :slight_smile:

Kind regards

robert

···

On Wed, Sep 21, 2016 at 8:42 PM, Kevin Deisz <kevin.deisz@gmail.com> wrote:

I've been struggling with something for a while and was hoping someone who
knows more about me than this would be able to help. I have this gist:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67\. I'm
attempting to build in generic callbacks that I can port into a number of
our gems here (this is not an invitation for a discussion on the merits of
callbacks).

I've got them working nicely for before and after callbacks. My issue comes
with around callbacks. I can get them to work if I explicitly look for a
block argument and call it (as in this line:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67#file-main-rb-L30\)
but I can't get it to work if I yield (as in this line:
https://gist.github.com/kddeisz/d975ef9a5e45a88bacb03e9f2c1fcf67#file-main-rb-L35\).

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Note that this doesn't work:

irb(main)> a = lambda { puts "yielding"; yield }
=> #<Proc:0x007ff421b4e408@(irb):13 (lambda)>

irb(main)> a.call { puts "hello" }
yielding
LocalJumpError: no block given (yield)
from (irb):13:in `block in irb_binding'
from (irb):15
from /usr/local/google/home/mdemello/.rbenv/versions/2.3.1/bin/irb:11:in `<main>'

i.e. the block passed to Proc#call does not get passed to the lambda itself.

But FWIW, this does:

    A = lambda {|&b| puts "yielding"; b.call }

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;