Forum: JRuby Any good workaround for LocalJumpError?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Gary L. (Guest)
on 2009-05-19 07:33
(Received via mailing list)
Hi All,

I was trying to implement a callback mechanism in JRuby that looks like
the following:

class Engine
  def initialize()
     @b=[]; @data = 1;
  end

  def add_listener(&b)
    @b << b;
  end

  def fire_event()
    @b.each do |b|
       puts "calling listener"
       begin
          b.call(@data)
       *rescue LocalJumpError*
       end
       puts "done calling listener"
    end
  end
end

engine = Engine.new;
engine.add_listener do |data|
  if data == 1
     puts "data is 1"
     return
  else
     # do something else
  end
end
engine.fire_event();

This code works fine with Ruby but not with JRuby 1.1.6.  The code jumps
right out of the b.call(@data) and LocalJumpError was never getting
thrown.  Some googling shows that there were several bugs filed against
this so I suppose this is a known issue.  But my question is, what would
be the best work around for this?

1. I suppose I can ask caller to always pass in a lambda to my
add_listener function, but that makes the syntax looks ugly for the
caller.
2. I suppose I can ask add_listener caller not to use return in their
block or thrown some special exception to terminate their code.  But
this could be ugly too.

Any other possible options or workarounds?

Thanks,

--Gary
Logan B. (Guest)
on 2009-05-19 18:35
(Received via mailing list)
Use next instead of return when you want to get out of a block that
won't be executed in the local scope.

Logan B.
removed_email_address@domain.invalid
http://www.logustus.com
Charles Oliver N. (Guest)
on 2009-05-19 20:15
(Received via mailing list)
I concur...the reason this raises LocalJumpError is because...it's a
local jump error. Although we endeavor to raise appropriate errors in
all cases, code that swallows errors as expected is generally bad form.

Try next and see if it solves your issues.

Logan B. wrote:
>>
>>   end
>>   end
>> end
>> caller.
>> 2. I suppose I can ask add_listener caller not to use return in their
>> block or thrown some special exception to terminate their code.  But
>> this could be ugly too.
>>
>> Any other possible options or workarounds?
>>
>> Thanks,
>>
>> --Gary
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Gary L. (Guest)
on 2009-05-20 02:07
(Received via mailing list)
Kool, next seems to do the trick.  "next 123" can also returns the value
123 back to the my add_listener function.  Though I still think using
return is cleaner from the syntax point of view (so the caller feel he
is writing a function rather than a block of code), but I guess I can
live with using next.

Coming from the Java world, I have always thought passing block is
similar to passing a function pointer.  But I didn't realize that block
handles return differently than a function.  The whole lambda and proc
thing seems rather confusing to me :(

In any case, appreciate for your helps :)

--Gary

Charles Oliver N. wrote:
>> Logan B.
>>> class Engine
>>>        puts "calling listener"
>>> engine.add_listener do |data|
>>> never getting thrown.  Some googling shows that there were several
>>>
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Ricardo T. (Guest)
on 2009-05-20 02:18
(Received via mailing list)
I don't think next is absolutely required. As long as the return in not
nil, anything will do. We had the same problem some months ago, and
fixed it by making the last line of the function simply "true". I'm not
sure if this still applies.

regards,
Ricardo

Gary L. wrote:
>
>>
>>>> Hi All,
>>>>     @b << b;
>>>>     end
>>>>   end
>>>> caller.
>>
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Gary L. (Guest)
on 2009-05-20 02:41
(Received via mailing list)
You are right.  I guess my example was not clearly demonstrate what I
wanted to do.  I am looking for a way to return in the middle of
function when some condition meets, rather than using a lot of if/else
statement.  You are correct.  If I want to return something in the last
statement, I do not need to use a "next".

Thanks,

--Gary

Ricardo T. wrote:
>> value 123 back to the my add_listener function.  Though I still think
>>
>>> Logan B. wrote:
>>>>>
>>>>>   end
>>>>>   end
>>>>> end
>>>>> 2. I suppose I can ask add_listener caller not to use return in
>>> ---------------------------------------------------------------------
>>    http://xircles.codehaus.org/manage_email
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Charles Oliver N. (Guest)
on 2009-05-20 07:03
(Received via mailing list)
Gary L. wrote:
> Kool, next seems to do the trick.  "next 123" can also returns the value
> 123 back to the my add_listener function.  Though I still think using
> return is cleaner from the syntax point of view (so the caller feel he
> is writing a function rather than a block of code), but I guess I can
> live with using next.
>
> Coming from the Java world, I have always thought passing block is
> similar to passing a function pointer.  But I didn't realize that block
> handles return differently than a function.  The whole lambda and proc
> thing seems rather confusing to me :(

To you and us both. It's definitely been organically grown, and only a
handful of people in the world can enumerate all the differences.

And the return thing takes some getting used to, especially since it's
not really consistent (return in lambda returns from lambda; return in
block/proc returns from containing method or raises error). But it's
difficult to work around if you want to be able to do "non-local"
returns and still have lambdas work like simple functions.

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
This topic is locked and can not be replied to.