Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Methods and blocks - not that clear when blocks passed into methods 1

Status
Not open for further replies.

p357

Technical User
Apr 21, 2009
2
AU
My first post in this site. I'm currently learning Ruby and have been fiddling with methods and blocks. Coming from other programming languages, notably Basic based, a little Java & C++, I find that passing blocks into methods is a little cryptic. What I mean is that when reading a method description (definition) there is no reference made to the fact that a block could be passed in as an argument. To me, it appears as if the method has to be read in conjunction with how the method is actually called in order to know if a block is passed or not. If my assertion is correct then the actual method call(s) in source code could be 100's of lines away from the method definition.

Is this how things are or are there some techniques to smooth this process somewhat?

Steve
 
Hi

Steve said:
Coming from other programming languages, notably Basic based, a little Java & C++, I find that passing blocks into methods is a little cryptic.
The code blocks in other languages are usually called "callback functions" and usually are just regular functions. AFAIK only Clipper has similar code blocks, delimited with [tt]{ || }[/tt]. So coming from other languages rarely helps with the syntax, but the concept has nothing new.

Let us take an example : sort some letters first alphabetically, then alphabetically but with vowels first.
Ruby:
vowel='aeiou'
data=['q','w','e','r','t','y','u','i','o','p']

alpha=data.[url=http://ruby-doc.org/core/classes/Array.html#M002208]sort[/url]
alter=data.[url=http://ruby-doc.org/core/classes/Array.html#M002208]sort[/url] { |a,b| (vowel.index(a) && ! vowel.index(b))?-1:(vowel.index(b) && ! vowel.index(a))?1:a<=>b }
Perl:
$vowel='aeiou';
@data=('q','w','e','r','t','y','u','i','o','p');

@alpha=[url=http://perldoc.perl.org/functions/sort.html]sort[/url] @data;
@alter=[url=http://perldoc.perl.org/functions/sort.html]sort[/url] { (index($vowel,$a)!=-1 && index($vowel,$b)==-1)?-1:(index($vowel,$b)!=-1 && index($vowel,$a)==-1)?1:$a cmp $b } @data;
JavaScript:
vowel='aeiou'
data=['q','w','e','r','t','y','u','i','o','p']

alpha=data.[url=http://devguru.com/technologies/javascript/10559.asp]sort[/url]()
alter=data.[url=http://devguru.com/technologies/javascript/10559.asp]sort[/url]( function(a,b) { return (vowel.indexOf(a)!=-1 && vowel.indexOf(b)==-1)?-1:(vowel.indexOf(b)!=-1 && vowel.indexOf(a)==-1)?1:a<b?-1:a>b?1:0 } )
In all three cases first we let the [tt]sort[/tt] method/function do its default job, then we gave it a code block/block/callback function to get a special ordering.

Now what makes the Ruby way more cryptic then the others ?
Steve said:
What I mean is that when reading a method description (definition) there is no reference made to the fact that a block could be passed in as an argument.
The code block is just a parameter. You either know what kind of parameter can you pass to a method/function, or not. I would say, this is the same for all languages and for all parameter types.
Steve said:
If my assertion is correct then the actual method call(s) in source code could be 100's of lines away from the method definition.
Correct. Also the place(s) where a String/Integer/whatever parameter is used, can be anywhere in the code.

Note that is not mandatory to make your methods to use code blocks. And while in core classes most of the code blocks are used for iterating, many times you can replace them with old-school looping statements :
Code:
data.each do |one|
  print one,' is ',vowel.index(one)?'':'not ',"vowel\n"
end

for i in 0...data.length do
  print data[i],' is ',vowel.index(data[i])?'':'not ',"vowel\n"
end
So for the beginning, if they hinder your productivity, you can quite ignore the existence of the code blocks.

If you have question related to a specific situation, show some code.

Hopefully I did not misunderstood your question.


Feherke.
 
Thank you Feherke for such a considered response, I know that it wasn't just a quick two minute, write something, type of comment.

The thrust of my question surrounded the fact that a block could be passed implicitly. From other sources (forums & books) I've since become aware of the explicit version of using the ampersand. As time goes on, and I gain a bit of experience, I will probably revert to the implicit way of doing things as they are done in other areas (none come to mind at present).

As an aside, callback functions, recursive routines, etc. whatever the language I find to be very confusing. ie. the factorial problem implemented as a recursive routine, yes I understand the flow but the fact that it calls itself, which calls itself, which calls itself... well it's something what I consider the more difficult or slower (as in my thinking) parts of the language to come to grips with.

As another aside, and quite fortuitously, you've used the 'vowel' examples. This will help me convert some old C++ problems, remove vowels from a string.

Steve
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top