This post originated from an RSS feed registered with Ruby Buzz
by Agnieszka Figiel.
Original Post: On blocks and discovering Ruby through C (!)
Feed Title: agnessa's blog
Feed URL: http://blog.agnessa.eu/xml/rss/feed.xml
Feed Description: ruby and rails impressions from a beginner developer
I finally started using blocks in Ruby :) It took me a long time to get used to this construct and actually start thinking in terms “this is a good place to use a block”. Which makes me suspect that even though I code in Ruby most of the time now, I still think in Java :( Apparently what helped me grasp blocks is C :) I wouldn’t think it would be more similar to Ruby than Java in any aspect, but…
Passing blocks of code into functions in Ruby is quite similar to passing function pointers in C not only in that they both look weird :) In Ruby you’d call a function passing a block like:
“block’s params” can be one or more parameters. A block can return a value, so it’s like an anonymous function. And a function could behave differently if the block was not supplied – it could test it with the block_given? method.
In C you’d first define a function to be passed, then pass a pointer to this function as an argument and call the pointer as if you were calling the function.
A situation where this can be applied is when you have a method which could be used for different purposes if a a small part of it could be altered as needed. Typical example – sorting a collection. The sorting method iterates over elements, compares them and rearranges them accordingly. Being able to define how the method should compare elements let’s us easily reuse the same sorting routine.
In C we can use the standard (stdlib.h) qsort function by passing it the comparing function pointer. qsort is declared as follows:
So the signature of the comparing function should be:
int compare_sim_reports (const void * a, const void * b)
and it should return
< 0 if a should go before b
0 if a is equal to b
> 0 if b should go before a
In Ruby we can use the sort function (which is a quicksort) and pass it a block with the comparator code like this:
base.sort {|a,b|
...
}
The block should return:
-1 if a should go before b
0 if a is equal to b
1 if b should go before a
For the simplest sorting cases you’re good to go with the <=> operator which returns -1, 0, 1 applying natural ordering:
base.sort{|a,b| a <=> b}
Talking of sorting – here’s a nice article by Wayne Conrad, which compares quicksort and combsort in C++ and Ruby. I’m pasting his performance results for sorting 10000 integers: