Caleb Clausen wrote: > Here's the shorter of his two of his attempts to write an andand macro > that operates like the && operator: > > called_by_name(:our_and) { |x,y| > if temp = x > y > else > temp > end > } > > Not so bad in itself, but all called_by_name's must be wrapped in a > 'with', which must get tiresome. The use of "with" is a deliberate design choice. Rather than making macros global and "automagical," you state what you are using and where you are using it. This is somewhat akin to writing 'require such-and-such' in each ruby source file. Of course, some people like magic, and if you look at Rails, the initializers and environment.rb file allow you to sprinkle magic throughout your project implicitly. My feeling when I designed rewrite was that that if I started with explicit "with," it would easy to build implicit into a project or framework later. > The longer one is too horrible to contemplate. > Speak for yourself ;-) > The equivalent in RubyMacros is something like this: > > macro andand(a,b) > :( if temp = ^a > ^b > else > temp > end > ) > #or maybe just :( ^a && ^b ) > end :( ^a && ^b ) is a little too metacircular for my taste, but I put it to you that rewrite allows you to define your own syntactic replacement using && if you want to. Now to get more specific. called_by_name is actually not a way of doing macros, it's a way of writing functions with call by name semantics. Rewrite actually provides a facility for code rewriting, which is one level *above* simple unhygienic macros. A traditional unhygienic macro is a way of saying "when you see something that looks like a method call, replace it with the following code, performing substitutions here and here and here." Rewrite supports this as well as a number of other arbitrary rewriting rules. For example, you can say "when you see foo.select { ...blah... }.map { ...blah-blah }, replace it with a single call to .each that performs the selction and mapping with out iterating over the collection twice. Now, called_by_name is actually a macro written using rewrite. So it's a meta-macro. I would say that gievn your example, the macro is better because it does not "compile" into a function call, whereas anything built with called_by_name will be rewritten as a function call. If what you want is the fastest, tightest code, use a ruby macro or use rewrite to directly rewrite the function call as an if statement. If you want to compare rewrite and ruby macros more directly, there's a little thing I wrote called Unhygienic. It does code rewriting "by example." Now, I use the term "andand" to refer to http://andand.rubyforge.org/, so here is how to write part of that gem using Rewriting by example: Unhygienic.from(:receiver, :message, [:parameters]) { receiver.andand.message(parameters) }.to { lambda { |andand_temp| andand_temp.message(parameters) if andand_temp }.call(receiver) } By the way, I use lambdas a lot in my rewrites to try to alleviate the pain of Ruby's scoping rules. If you like to live a little more dangerously (and the example above does), this rule can be made shorter: Unhygienic.from(:receiver, :message, [:parameters]) { receiver.andand.message(parameters) }.to { temp.message(parameters) if (temp = receiver) } Both examples are longer than the macro or called_by_name definitions. The "from" says "here is a snippet of code where receiver, message, and parameters are placehilders for an expression, and expression, and a list of expressions. The "to" says "when you find that, replace it with this, plugging in the placeholders." The idea here is that you can use any arbitrary ruby expression, not just something that looks like a function call. In this case, you are making something that looks like a method call expand into something else entirely. My motivation with Rewrite was very specific: I was trying to show that we have alternatives to wide scale opening of core classes to implement DSLs and syntactic abstractions. This goal necessarily encompassed providing an alternative to existing idioms like #andand or Symbol#to_proc or #try. The goal of Ruby macros seems to be a little different, and thus the two gems work in different ways. Overall, I wish Ruby macros every success and hope that people get excited about syntactic abstractions. -- Posted via http://www.ruby-forum.com/.