Da Utorok 07 Februr 2006 18:53 Sam Kong napsal:
> Hi!
>
> A friend of mine challenged me with Smalltalk.
> He's a big fan of Smalltalk.
> He asked me what I can do if I want to add "try ~ finally ~" systax in
> Ruby.
> Yes, we already have "begin ~ ensure ~".
> But he asked me whether Ruby is flexible enough to extend such a thing
> without changing the language itself.
> He said that Smalltalk doesn't have "try ~ finally ~" in the language
> but can be defined without changing the language.
>
> Personally, I don't think such flexibility is really needed.
> However, I want to defend Ruby.
> How would you react such an attack?
>

Well, my first reply would be that noone really understands how the hell 
Smalltalk exceptions really work anyway - last time I played around with ST, 
I remember an ifCurtailed: method (remembered because I have no idea what 
"curtailed" means), some four variants on that one, and then at least two 
more basic ifSomething: methods plus variants that had something to do with 
exception handling. The second reply would be that custom syntax features are 
only marginally useful in production code and tend to be rather confusing.

And of course to top the whole thing off, yes, you can implement something 
like custom extension handling syntax.

As to the actual implementation, I can at best think of a solution that wraps 
around begin / rescue / ensure - you still have to have some support for 
nonlocal exits from the runtime, and ruby doesn't quite let you manipulate 
the interpreter at runtime as you can a Smalltalk one. And I don't feel like 
learning interpreter hacking just for this example to make myself some low 
level access to the interpreter stack.

Yaaanyways, here cometh the (probably incorrect and definately flaky) code:

	def try_catch_finally(try_block, catch_block, finally_block)
		begin
			try_block[]
		rescue => ex
			catch_block[ex]
		ensure
			finally_block[]
		end
	end

	try_catch_finally proc {
		puts "foo"
		raise
	},
	proc { | ex |
		puts "bar"
		puts ex.class.name
	},
	proc {
		puts "quux"
	}

If that's not enough, accuse your friend of being a nitpick ;P