From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2003-04-17T15:59:33+09:00 Subject: Re: Newbie proc question In article <8fd3ee12.0304161737.32de03da@posting.google.com>, James Toomey wrote: >Can anyone help reduce my confusion? I think I understand the "how" of >proc blocks, but I still don't get the "why," particularly with a >dynamically passed block of code, like in the following sample: > >def dummyMethod(&dynamicBlock) > dynamicBlock.call >end > >dummyMethod { > puts 'This is line 1 of custom block code' > puts 'This is line 2 of custom block code' >} > >From what I've read, the proc block feature isn't found in many >languages, and makes Ruby (and others like Lisp) much more flexible >and powerful. However, I don't quite grasp why. Is the benefit that >you don't need to modify "dummyMethod" at all, but rather just modify >the code within the block? No, that wouldn't be much benefit. >And if this is the case, why is that >better? After all, if you have to make code changes, you still have to >change it somewhere, regardless of whether you're changing it in >"dummyMethod" or in the code block. Right. >I don't see the benefit of passing >blocks of code around instead of just including that code in the >method you're calling. >I'm coming at this from a Visual Basic background, so I'm sure I'm a >bit like a Neanderthal being shown a power drill and wondering why >it's any better than my rock tool. ;-) >I get the feeling that proc blocks >can do great things, but I just don't see why. Yes, you can do great things with them. Maybe a real world example is in order. I've created a hardware simulator using Ruby (RHDL) and there is a step method that steps to the next simulation 'time' (think of it kind of like using 'step' in a debugger to step to the next line in a program). At first my step method didn't take any arguments, but then I got the idea that a user might want to display some information or perhaps change some input(s) at each time step, so I made it so that step could take a block and then remember that block until another block is given (saves a lot typing for the user). Without going into a lot of details, here's how it works in practice: #given some setup of signals: clk, rst, output: step { clk = clk.inv #invert clk signal #display signal values: puts "clk=#{clk}, rst=#{rst}, output=#{output}" } So I guess the main point here is that the user of my API can add their own code to specify what should be done from one step to another. The user could put anything between the '{}'s. It essentially means that my program becomes more flexible because I've allowed users to pass in their own code. Of course, this isn't the only advantage of blocks. Probably the biggest use is in iterators (like Array#each) - but the advantage is similar: it allows the user of the iterator to specify some code that gets run at each step of the iteration. So to summerize: A big reason to allow a method to take a block is to allow users of your code to pass in code. This makes your code more flexible (usable in a greater number of situations) because when you allow blocks you're essentially saying that you are not trying to foresee every possible way that your code should be used, so you're allowing the user of your code to insert code of their own to do what they need to get done. Make sense? This probably isn't the only rationale for using blocks. I'm sure others will provide other reasons. The other thing to add here is that Ruby's block mechanism is quite elegant and unique - it essentially allows you to create domain specific languages that look syntactically very natural. (RHDL is an example of this) Phil