From: "T. Onoma" Date: 2003-11-23T20:31:13+09:00 Subject: Re: open-uri patch, added progress_proc hook On Sunday 23 November 2003 02:24 am, Tanaka Akira wrote: > In article <200311221024.05642.transami@runbox.com>, > > "T. Onoma" writes: > > opts = OpenUriOptions.new > > def opts.progress_bar( percent_done ) > > puts "Yeah, we're at " + percent_done + "% now!" > > end > > open( "http://whytheluckystiff.net/why.yml", opts ) > > I can't see any benefits over non-singleton method version: It's actually kind of mind boggling just how nearly identical these two code snippets are. opts = OpenUriOptions.new opts.progress_bar do |percent_done| puts "Yeah, we're at " + percent_done + "% now!" end open( "http://whytheluckystiff.net/why.yml", opts ) opts = OpenUriOptions.new def opts.progress_bar( percent_done ) � puts "Yeah, we're at " + percent_done + "% now!" end open( "http://whytheluckystiff.net/why.yml", opts ) If fact the distinction is wholly in the 2nd line where the do moves over to def and the | | become ( ). That's it! And of course the end result is exactly the same. So... > Why singleton? There's something compelling about them in conjunction with Duck Typing. But it has less to do with the front-end, as show here, and more to do with with the implementation code that underlys these two examples. The distinction is one of specific/active verses general/passive programming. The first example requires that the implementation be more active and specific, taking care of all the assignments to the opts with built in methods. class OpenUriOptions attr_reader :progress_block def progress_bar( &progress_block ) @progress_block = progress_block end end ... def open(name, opts, &block) ... opts.progress_block.call(t) if opts.progress_block ... end The second is passive and general, and needs do nothing special to gain new functionality except to ask if it has been given it. class OpenUriOptions end ... def open(name, opts, &block) ... opts.progress_block(t) if opts.respond_to?(:progress_block) ... end So the advantage is having less implementation code. In fact you could write a whole class that had nearly zero assignment code and all respond_to? activators. (That would be interseting to see actually.) On the downsie it might have some small performance loss, and, of course, we're simply not used to the idea. Perhaps you see it differently, but for me, not only does it seem odd, but it feels new and exciting at the same time. But hey, I'm a wild and crazy kind of guy. -t0