`#catch'ing many symbols

Hello,

I find it odd that #catch can’t take more than one symbol. It doesn’t
scale well if you want many symbols and makes conditional catching a
chore:

catch 2 syms

catch :one do
catch :two do
stuff
end
end

catch one sym and conditionally catch another

catch :x do
if condition
catch :y do
stuff
end
else
stuff
end
end

This looks better to me:

catch 2 syms

catch :one, :two do
stuff
end

catch one sym and conditionally catch another

catchsyms = condition ? [:x, :y] : [:x]
catch *catchsyms do
stuff
end

Can we get this changed?

“George Ogata” g_ogata@optushome.com.au schrieb im Newsbeitrag
news:874qsp7o5d.fsf@optushome.com.au…

Hello,

I find it odd that #catch can’t take more than one symbol. It doesn’t
scale well if you want many symbols and makes conditional catching a
chore:

catch 2 syms

catch :one do
catch :two do
stuff
end
end

catch one sym and conditionally catch another

catch :x do
if condition
catch :y do
stuff
end
else
stuff
end
end

This looks better to me:

catch 2 syms

catch :one, :two do
stuff
end

catch one sym and conditionally catch another

catchsyms = condition ? [:x, :y] : [:x]
catch *catchsyms do
stuff
end

Can we get this changed?

I don’t think so. Problem is that catch returns the instance associated
with the throw and when catching multiple symbols you can’t distinguish
what happened. In that case a single symbol is enough because you can use
the returned element to carry information about the event:

irb(main):012:0> x = catch :foo do
irb(main):013:1* throw :foo, “result”
irb(main):014:1> end
=> “result”
irb(main):015:0>

This is sufficient for your non conditional catch example. Conditional
catch does not make sense IMHO. What do you want to achieve with that?

Regards

robert

“Robert Klemme” bob.news@gmx.net writes:

I don’t think so. Problem is that catch returns the instance associated
with the throw and when catching multiple symbols you can’t distinguish
what happened. In that case a single symbol is enough because you can use
the returned element to carry information about the event:

Thanks, I’d forgotten about the second throw arg. I guess that
satisfies the uncondtional case. Conditional was really the one I was
interested in, though.

Conditional catch does not make sense IMHO. What do you want to
achieve with that?

I think it can be useful in recursive scenarios. To unwind the stack
to the first call, you catch the symbol only if it’s the first
invocation.

In my case, I have a stackable command interpreter interface
(“stackable” in the sense that you can recursively invoke one while
one is running, like the way you sometimes nest shells). One command
exits just the topmost layer to return to the one below. Another
exits the whole stack.

To implement this, the former command throws :done, the latter :quit.
Only the bottom-most interpreter catches :quit, the others just catch
:done.

I suppose there’re few uses for multi-catching though, so fair enough.
If it’s a harmless extension, though…

“George Ogata” g_ogata@optushome.com.au schrieb im Newsbeitrag
news:878yhy0xwl.fsf@optushome.com.au…

“Robert Klemme” bob.news@gmx.net writes:

I don’t think so. Problem is that catch returns the instance
associated
with the throw and when catching multiple symbols you can’t
distinguish
what happened. In that case a single symbol is enough because you can
use
the returned element to carry information about the event:

Thanks, I’d forgotten about the second throw arg. I guess that
satisfies the uncondtional case. Conditional was really the one I was
interested in, though.

Conditional catch does not make sense IMHO. What do you want to
achieve with that?

I think it can be useful in recursive scenarios. To unwind the stack
to the first call, you catch the symbol only if it’s the first
invocation.

Well, that’s not too difficult, since one often has an entry method to
recursion:

def enter(*args)
catch :quit do
catch :done do
recur_impl(*args)
end
end
end

def recur(*args)
catch :done do
recur_impl(*args)
end
end

def recur_impl(*args)
if …
recur x
else

end
end

In my case, I have a stackable command interpreter interface
(“stackable” in the sense that you can recursively invoke one while
one is running, like the way you sometimes nest shells). One command
exits just the topmost layer to return to the one below. Another
exits the whole stack.

Is that really a case for recursion?

To implement this, the former command throws :done, the latter :quit.
Only the bottom-most interpreter catches :quit, the others just catch
:done.

I suppose there’re few uses for multi-catching though, so fair enough.
If it’s a harmless extension, though…

As I said, I don’t think it’s a reasonable extension…

Regards

robert

“Robert Klemme” bob.news@gmx.net writes:

Well, that’s not too difficult, since one often has an entry method to
recursion:

def enter(*args)
catch :quit do
catch :done do
recur_impl(*args)
end
end
end

def recur(*args)
catch :done do
recur_impl(*args)
end
end

def recur_impl(*args)
if …
recur x
else

end
end

It’s not a case of it being difficult, I just think it’s more
naturally expressed the other way. Each to their own, I suppose.

In my case, I have a stackable command interpreter interface
(“stackable” in the sense that you can recursively invoke one while
one is running, like the way you sometimes nest shells). One command
exits just the topmost layer to return to the one below. Another
exits the whole stack.

Is that really a case for recursion?

I think it’s easiest done so, yes.

As I said, I don’t think it’s a reasonable extension…

K.