Higher Order Messaging in Ruby
Having played around with Ruby for some six months now, I feel confident enough to make my first post on the subject. It’s going be about Higher Order Messaging, and it’s more of an expansion on an excellent description by Nat Pryce. I’m writing this post partly because I feel my implementation is a tad better (less cumbersome, as one need not define a class for each new method), and partly because it feels like his post has gone largely unnoticed.
First of all, let’s talk about blocks. Anyone familiar with Ruby will have some knowledge of blocks. Blocks in Ruby is a way to pass a chunk of code as argument to a function; blocks are also full closures, so they may reference any variables that exist in the scope in which they were declared. An example of block usage:
[0,1,2,3,4].select { |val| val.nonzero? }
=> [1,2,3,4]
As you may know, Enumerable#select loops through a collection and returns a new collection containing those elements for which the block evaluates to true. So, the example above produces the array [1,2,3,4], since Numeric#nonzero? will return false for the first element in the array and true for the others.
I expect this is nothing new for most people. Often however, as in the above example, this syntax seems a little verbose.
Using Symbols
You may have come across a little method in the Ruby Extensions project named Symbol#to_proc. In fact, it seems like this hack soon will be an official part of Ruby. Now to achieve the same results as the example above, we can use,
[0,1,2,3,4].select(&:nonzero?)
=> [1,2,3,4]
which is, if nothing else, more compact. Don’t get me wrong, I love this hack. But some object that this syntax is a bit ugly, and I agree partly, so we want to do this some other way, if possible. By understanding how calling methods works in Ruby, we can construct an alternate syntax.
Using Higher Order Messaging
Higher order messaging consists of the idea that method calls (messages), can be passed as arguments. I’ll spoil the surprise and show right away how our new syntax will look:
[0,1,2,3,4].where.nonzero?
=> [1,2,3,4]
Looks good, doesn’t it? It looks like the method where takes a method call (nonzero?) as its argument, forwards it to each element and collects those for which it returns true. That is kind of what happens, but in a much more complicated way. Most of the magic lies in the where method; it returns an object that responds to nonzero?. The object that is returned from where is an instance of HigherOrderMessage:
class HigherOrderMessage
instance_methods.each { |method| undef_method(method) unless method =~ /__(.+)__/ }
def initialize(&proc)
@proc = proc
end
def method_missing(id, *args)
@proc.call(id, *args)
end
end
It might look a bit confusing, but it’s actually very simple. First note that all functions that aren’t vital (such as __send__) are unlinked, so they may not be called. Second, when constructing a HigherOrderMessage, a block must be supplied, which is stored in the object. Finally, method_missing is defined. This method is a bit special, because it’s called whenever another method doesn’t exist. The first parameter is the name of the method that was attempted; the second parameter is its arguments.
So far, this code does nothing. It’s a mere skeleton to build some functionality from. This is done by in the implemention of Enumerable#where:
module Enumerable
def where
HigherOrderMessage.new do |id, *args|
select { |x| x.__send__(id, *args) }
end
end
end
[0,1,2,3,4].where.nonzero?
=> [1,2,3,4]
Let’s dissect the example above; first where is called. What happens is that a new HigherOrderMessage object is created and returned (for brevity, this object will henceforth be referred to as hom). Furthermore, this object has one instance variable—@proc—that contains the code block that was passed to it.
Then, we’re trying to call hom.nonzero?. Since this method doesn’t exist, hom.method_missing(:nonzero?) is called instead. method_missing forwards the method id and its parameters to the block that is stored in @proc. This block consists of a call to select, which in our example evaluates to { |x| x.__send__(:nonzero?) }, equivalent to { |x| x.nonzero? }. Finally, the array that’s generated is returned.
Now you may realize why all defaults methods (those inherited from Object) were undefined: it’s simply so that all methods are forwarded to method_missing. Otherwise, some_array.where.frozen?, for example, wouldn’t work, because it would check whether the HigherOrderMessage object is frozen or not.
Some Other Methods
Let’s construct some other useful methods: do_each, do_collect and do_inject.
module Enumerable
def do_each
HigherOrderMessage.new do |id, *args|
each { |x| x.__send__(id, *args) }
end
end
def do_collect
HigherOrderMessage.new do |id, *args|
collect { |x| x.__send__(id, *args) }
end
end
# Requires Enumerable#inject
def do_inject(start_value)
HigherOrderMessage.new do |id, *args|
inject(start_value) { |a,x| a.__send__(id, x, *args) }
end
end
end
a, b = [0,1], [1,2]
[a,b].do_each << 3
[a,b]
=> [[0, 1, 3], [1, 2, 3]]
[0,1,2,3,4].do_inject(0).+
=> 10
[0,1,2,3,4].do_collect * 2
=> [0,2,4,6,8]
The first line adds a new element, 3, to the array. The second like computes and returns the sum of the given array: 10. The third maps the message *(2) to all elements in the array. All examples demonstrate something that would have been impossible to do with Enumerable#to_symbol: when passing a method call you pass both the method name and its arguments, but when you pass a symbol that’s converted to a proc you can’t pass any arguments. Thus, you could never do [a,b].each(&:<<(3)).
Of course, even more complex stuff can be done. Here’s an example of a method that, seemingly, takes two methods as parameters.
module Enumerable
def having
HigherOrderMessage.new do |id, *args|
HigherOrderMessage.new do |secid, *secargs|
select { |x| x.__send__(id, *args).__send__(secid, *secargs) }
end
end
end
end
[0,1,2,3,4].having.succ < 3
=> [0,1]
The having method, apart from being very useful, demonstrates something interesting about higher order messaging: it can be chained. Not only does having return a HigherOrderMessage instance, even the block in @proc returns one! That means that [0,1,2,3,4].having.succ returns a HigherOrderMessage object that takes yet another function (in our case, <), applies succ to each element and checks it against <(3). Note that this is different than [0,1,2,3,4].succ.where < 3, which would return an array of successors rather than objects from the original array.
A warning: while operators like <, >, ==, and so on may be used in these functions, != mustn’t. From my understanding this is due to a != b being a short form of !(a == b). (E.g., [0,1,2,3,4].succ.where != 3 would expand to !([0,1,2,3,4].do_collect.succ.where == 3), which is false.
Final Words
This is not meant as a replacement for blocks in collection manipulation, but maybe a replacement for Symbol#to_proc. Higher order messaging has, in my opinion, the following advantages:
- The syntax less wordy than using a block.
- It’s more flexible than using
Symbol#to_procsince you’re effectively forwarding a method call rather than just a method.
It’s not without its problems though. First of all, I’d like to see a version where we can drop the “do_” part of the methods that already exist in Enumerable, and instead have a general function that can either take a block and work like normal, or not take one and behave like a higher order message. And secondly, the implementation itself: right now, this is more of a hack than anything else. It’s probably slower than using a block. And it’s not really tested. At all.
October 9th, 2006 at 12:22
Sir, this post has left me humbled and afraid. And a little peckish.
October 11th, 2006 at 22:14
Here’s an idea - let’s just modify the methods in Enumerable to accept arguments instead of adding extra syntax that does nothing more than shift the block to the left.
- Dan
October 11th, 2006 at 22:39
This is so lovely. I’ve never much liked Ruby’s block messaging syntax, despite being impressed by its power. I am very anxious to see how the community responds as this approach matures.
October 12th, 2006 at 19:11
Thanks! You teach me a lot.
Inspired by your work, I think it may be more natrual to keep ’select’ as the HOM name.
class Array
alias :old_select :select
def select(&p)
if block_given? # conventional call, followed by a block
old_select(&p)
else
HigherOrderMessage.new do |id, *args|
old_select { |x| x.__send__(id, *args)
end
end
end
So that we can say:
(1..100).to_a.select.odd?
October 12th, 2006 at 19:13
HTML support?
class Array
alias :old_select :select
def select(&p)
if block_given? # conventional call, followed by a block
old_select(&p)
else
HigherOrderMessage.new do |id, *args|
old_select { |x| x.__send__(id, *args)
end
end
end
October 12th, 2006 at 19:45
Thanks for the comments.
Daniel Berger:
I see what you mean. While the methods I wrote here were more meant to demonstrate what HOM is and what it can do, it’s true that blocks fills the same functionality and more. It’s still an interesting design pattern, if you ask me. So to clarify: using these specific methods in code for a real project is not something I advise, but learning what HOM is, that can be useful.
Mike Meng:
It might be a good idea; however, I’ve got something against overriding methods. So for this example I decided to make new methods instead. Oh, and by the way, I’m pretty much running default Wordpress, so markup in comments are a bit lacking (in fact, I don’t think any kind of markup is allowed). Sorry about that.
October 13th, 2006 at 05:15
Thanks. I agree your consideration. Since do_each, do_collect, do_inject and (if ‘do_select’ is used instead of ‘where’) do_select share almost same code, I suggest :
class Array
instance_methods.select {|m| [:select, :each, :collect, :inject].include? m.to_sym}.each {|m|
module_eval
October 13th, 2006 at 05:17
Hi Istarius, I’m not complaining, but your comment template system is REALLY broken!
Try paste my code again:
class Array
instance_methods.select {|meth| [:select, :each, :collect, :inject].include? meth.to_sym}.each do |meth|
module_eval
October 13th, 2006 at 05:19
Faint, I give up.
October 13th, 2006 at 12:19
It’s the default system, I guess I should try to find something else that works. And that’s only one of the little quirks I dislike about WP, I might be looking to move on to something else soon…
Anyway, I see what you’re getting at (I believe), and that’s an excellent idea.
October 14th, 2006 at 21:11
Check out Dr. Nic’s recent work on map_by_method.
December 5th, 2006 at 15:50
Cool! That’s a really nice redesign, much better than the way I wrote it originally.
Do you want to contribute that into the Homer project on RubyForge?
December 8th, 2006 at 11:29
Cheap 17…
Site 17…
December 8th, 2006 at 12:49
Read 4…
You 4…
January 10th, 2007 at 06:27
About ftop…
Site ftop…
January 10th, 2007 at 07:58
My italy…
Read italy…
January 10th, 2007 at 09:32
Blog topnado…
My topnado…
January 10th, 2007 at 11:10
Popular top…
Cheap top…
February 11th, 2007 at 03:11
Hello, my name is Alex, i’m a newbie here. I really do like your resource and really interested in things you discuss here, also would like to enter your community, hope it is possible:-) Cya around, best regards, Alex!
April 23rd, 2007 at 03:12
[…] A friend of mine sent me this link a while back on Higher Order Messaging in Ruby, which tracks back to this original post on HOM in Ruby and eventually tracks back to a presentation given on HOM in Objective-C. […]
May 13th, 2007 at 12:11
Hi My Name Is ivatnn.
May 15th, 2007 at 18:05
ABC24…
chuj w dupe policji…
May 30th, 2007 at 23:44
Hello! Good Site! Thanks you! zmhfuhyztiajew
May 31st, 2007 at 22:51
suzuki chicago…
ka-ka-sh-ka 4036326 Value information about suzuki chicago…
June 1st, 2007 at 02:04
2007 jeep tj…
mazda miata roll bar…
June 3rd, 2007 at 20:20
wrizk
June 3rd, 2007 at 20:22
cvqvoi
June 4th, 2007 at 15:58
chat latin yahoo…
ka-ka-sh-ka 4036326 Advantages of chat latin yahoo….
June 7th, 2007 at 20:10
mature ebony nude…
ka-ka-sh-ka 4036326 Aggregator of mature ebony nude sites…
June 7th, 2007 at 20:46
nn amateur teen…
ka-ka-sh-ka 4036326 nn amateur teen moves…
June 7th, 2007 at 21:07
Porno Tie…
Free Newest XXX Video…
June 9th, 2007 at 15:39
nude asian porn…
Features of nude asian porn….
June 9th, 2007 at 23:17
free nude indian models…
Fresh news on free nude indian models….
June 11th, 2007 at 12:40
Higher Order Messaging in Ruby…
[…]Higher order messaging is a pattern that allows a more object-oriented approach of manipulating objects, by accepting a method call as a parameter to another method. A rough version of this can easily be implemented in Ruby.[…]…
June 12th, 2007 at 21:56
http://3.kikysexx.info x
July 5th, 2007 at 20:50
grassrootsyouth…
grassrootsyouth…
July 11th, 2008 at 20:53
http://www.clubsguide.com.au/forum/viewtopic.php?t=1967
January 7th, 2009 at 04:05
esure car insurance car insurance esure
January 9th, 2009 at 00:51
hi
enj90i3ljsv42yoa
good luck
January 10th, 2009 at 13:43
hi
enj90i3ljsv42yoa
good luck
March 29th, 2009 at 22:42
Interesting article, i have bookmarked your site for future referrence :)
September 7th, 2010 at 13:04
Super artykul, dzieki!
September 9th, 2010 at 20:21
ciekawy artykuł, polecam uwadze, warto
September 28th, 2010 at 23:21
kqIVYR http://cgE8hcmk9Vvqlosr5wcBa6nk.com
October 6th, 2010 at 12:01
Very Good Site nonnude tween model 8-(( switerland teen models lcnxnm teen models depraved stnam teen potsdam model xkqtzc model boys tgp >:DDD
January 6th, 2011 at 03:50
It’s funny goodluck Theadulttube
6703 Porntoshare
7561 Dipvid
559616 Pornwondervids
78234 Pussism
:-[[ Pontuvideox
8-)) Barely18xxx
8-OO Sexvidia
:O Videhoe
ypdgl Deepworx
6777
January 7th, 2011 at 01:16
This might be a actually very good read for me, Ought to confess that you simply???¨º?¨¨re among the quite best bloggers I in fact noticed.Thanks for posting this informative article.
January 28th, 2011 at 09:31
,*. I am really thankful to this topic because it really gives up to date information *.~
March 7th, 2011 at 21:45
watch the green hornet movie [url=http://www.rhrealitycheck.org/user/downloadthegreenhornet2011]green hornet trailer[/url] download 2011 3D
March 26th, 2011 at 17:57
Good luck getting people behind this one. Though you make some VERY fascinating points, youre going to have to do more than bring up a few things that may be different than what weve already heard. What are trying to say here? What do you want us to think? It seems like you cant really get behind a unique thought. Anyway, thats just my opinion.
April 3rd, 2011 at 15:37
I wonder if some of this content may have been duplicated from elsewhere, it’s all over the net and various peoples websites, unless you’re the content’s creator?
April 4th, 2011 at 08:28
That is the appropriate blog for anybody who wants to find out about this topic. You realize so much its nearly exhausting to argue with you (not that I truly would need…HaHa). You positively put a new spin on a subject thats been written about for years. Nice stuff, simply great!
April 9th, 2011 at 04:47
we must definitely you need to be pleased for that mothers and fathers as an alternative to pondering the item
April 17th, 2011 at 10:15
The original online “no prescription necessary” pharmacy and prescription medication information site. - How much dosing - Buy cheap viagra .? pharmacology exam questions grayston company medical?..
April 17th, 2011 at 23:42
Make sure you excuse my my English speak, i am just schooling. I significantly like your site greatly, I find it quite attention-grabbing and that i saved a bookmark in my personal internet.
April 21st, 2011 at 04:47
Buy cheap Adobe Premiere CS5 Pro Oem Software Version
Buy cheap Acronis Disk Director Suite 10 Oem Software Version
Buy cheap Atomic Time Synchronizer 4.5 Oem Software Version
Buy cheap ConceptDraw MINDMAP for Projects 6.2.2.0 Oem Software Version
Buy cheap Systweak Advanced System Optimizer 3.0 Oem Software Version
buying online Utilities in Port St. Lucie
June 25th, 2011 at 17:30
Intressant inlägg och tack för att dela. Vissa saker här inne har jag inte tänkt på before.Thanks
July 15th, 2011 at 02:18
Have you ever thought about adding a little bit more than just your articles? I mean, what you say is important and all. However think of if you added some great images or videos to give your posts more, “pop”! Your content is excellent but with pics and clips, this site could definitely be one of the greatest in its niche. Superb blog!
July 15th, 2011 at 11:30
At times i ponder about why modern society has become just like this. It really is just depressing :(. I’m going to go consume a beer and relax now! sorry if i got everyone down.
July 17th, 2011 at 07:02
I am curious to find out what blog system you happen to be using? I’m experiencing some minor security issues with my latest website and I would like to find something more risk-free. Do you have any solutions?
July 19th, 2011 at 21:46
Auto Warranty …
[…]below you’ll find the links to some web sites that we believe you should see[…]…
July 20th, 2011 at 14:54
I like this article. I search it from google. Can I copy to my facebok? . Regards
July 28th, 2011 at 22:20
Between me and my husband we’ve owned more MP3 players over the years than I can count, including Sansas, iRivers, iPods (classic & touch), the Ibiza Rhapsody, etc. But, the last few years I’ve settled down to one line of players. Why? Because I was happy to discover how well-designed and fun to use the underappreciated (and widely mocked) Zunes are.
July 31st, 2011 at 08:01
You can never tell your good intentions when you just read and observe from the viewers point of view, that is unless you give a good comment such as this one! Great job mate.
August 6th, 2011 at 09:02
Very good publish, I identified this just in time. I’m gonna hold this web site bookmarked for future reseach. cheers Mate.
August 7th, 2011 at 10:44
Thanks sharing this kind of useful blog in order to people.I’ve been recently stopping by for some time now, i would like to inform you!
August 8th, 2011 at 23:55
Would you be concerned with exchanging links?
September 5th, 2011 at 18:55
The actual posting could share what it needs to convey to your scaners. It has been a very effective technique which resulted to some successful expenditure for anyone who have been lucky enough to find the item!
September 7th, 2011 at 04:04
Why did you come to ? sexy preteens
=[[[
September 8th, 2011 at 22:27
I sing in a choir nn pre models movies nud
15107
September 9th, 2011 at 02:24
I’d like to open an account www nude lolitas com 02407
September 11th, 2011 at 22:07
Jag var imponerad av hur du uttryckte dina tankar om I, Istarius » Blog Archive » Higher Order Messaging in Ruby. Jag kan inte tror att någon kan skriva en fantastisk historia som Thet om jag älskar I, Istarius » Blog Archive » Higher Order Messaging in Ruby.
September 21st, 2011 at 07:38
Howdy! Do you use Twitter? I’d like to follow you if that would be okay. I’m undoubtedly enjoying your blog and look forward to new updates.
September 21st, 2011 at 19:02
ixofjmfhbdzpguifnpc, http://www.ygaxbkvbxe.com kjjumuwpqe
September 22nd, 2011 at 16:47
How long are you planning to stay here? Nn Child Models Galleries 8985
September 23rd, 2011 at 08:47
I’d like to send this letter by Teenie Toplist 132
September 27th, 2011 at 20:59
You have a terrific blog here! would you like to make some invite posts on my blog?
September 27th, 2011 at 22:55
I have not checked in here for some time as I thought it was getting boring, but the last several posts are great quality so I guess I’ll add you back to my daily bloglist. You deserve it my friend
September 28th, 2011 at 04:49
We were at school together Nn Lolita Model
267
October 16th, 2011 at 16:31
Needed to send you that very little remark in order to say thank you the moment again for the incredible knowledge you’ve shared on this site. It’s really shockingly open-handed with people like you to supply easily exactly what a number of people might have sold for an e-book in order to make some profit for their own end, specifically considering the fact that you could have tried it if you desired. Those tricks also acted to become fantastic way to realize that other people online have similar passion the same as my own to figure out very much more in respect of this matter. I believe there are a lot more enjoyable opportunities in the future for folks who examine your blog post.
November 11th, 2011 at 02:08
How much is a First Class stamp? Preteen Models
=-((
November 15th, 2011 at 06:40
Thank you, I’ve just been searching for information about this topic for a whilst and yours is the greatest I’ve discovered till now. But, what in regards towards the conclusion? Are you sure concerning the supply?
November 27th, 2011 at 02:20
May His come bring you peace and blessings this Christmas !
December 6th, 2011 at 13:34
What would most of us do devoid of the magnificent thoughts you share on this website? Who comes with the tolerance to deal with essential topics in the interest of common readers like me? My spouse and i and my pals are very fortunate to have your website among the ones we often visit. Hopefully you know how much we enjoy your efforts! Best wishes from us all.
December 10th, 2011 at 16:01
Hey very cool website!! Man .. Beautiful .. Amazing .. I’ll bookmark your web site and take the feeds also¡KI am happy to find so many useful info here in the post, we need develop more strategies in this regard, thanks for sharing. . . . . .
December 15th, 2011 at 13:47
“The generals, who took power after the 18-day uprising that pushed Mubarak out, were clearly hoping their successful shepherding of election would deflate the wave of protests against them that erupted 10 days ago.
December 15th, 2011 at 23:15
That is truly brilliant news flash. I appreciate you for sharing the item with us all!
December 22nd, 2011 at 16:48
I was thinking if I could get this information in my site. I will provide a link to your website, can I?
December 23rd, 2011 at 08:28
I just subscribed to your website for much more great information, please do so!
January 4th, 2012 at 16:40
There are incredibly lots of details like this take into consideration. That’s a great point out talk about. I offer the thoughts above as general inspiration but clearly you’ll discover questions such as 1 you bring up the place that the most crucial thing will probably be inside the honest excellent faith. I don?t know if guidelines have emerged about such items as that, but I am positive that your job is clearly known as a fair game. Both boys and girls have the impact of basically a moment’s pleasure, for the rest of their lives.
January 16th, 2012 at 20:15
of course like your web-site but you have to check the spelling on several of your posts. A number of them are rife with spelling problems and I find it very troublesome to tell the truth nevertheless I will surely come back again.