Any good workaround for LocalJumpError?


#1

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


#2

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


#3

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

#4

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

#5

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

#6

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 :frowning:

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

#7

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 :frowning:

In any case, appreciate for your helps :slight_smile:

–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