: my Database $db = MySqlDatabase.connect(...); : $db.select * FROM Foo WHERE Foo.bar LIKE a%b;
To answer your actual question, you either need to have some keyword out front to start the alternate parsing, or you need to treat ".select" as an infix macro that has an ordinary expression on the left ($db) and a specially parsed argument on the right (* FROM Foo WHERE Foo.bar LIKE a%b)
This feels a bit clunky. The sort of hack one makes when its too late to fix it.
If we define .select as an infix macro, it is then not scoped to the invocant. This means that it would confict with any other .select method that one might wish to call. E.g.
$io.select(...);
(OK, thats not a good example, but you get the gist). If sure it would be possible to write the macro in such a way that it looks at its LHS arg -- and ignores itself if its not a Database object ... but that places an overly large burden on the macro writer. To avoid this burden, I'd like to propose C<macromethod> as a counterpart to C<submethod>. A macromethod would enable me to write an invocant-scoped macro, without polluting the lexical namespace:
class Database { ... macromethod select ($lhs, $rhs:) is parsed /<sql.select.body>/ { "$lhs.do_sql('select $rhs')" } }
Without this mechanism, then we need a way to prevent an infinite regress on macro processing. I am assuming that, if the output of a macro is a string, then that string will be re-parsed and any macros in it will be expanded. How would an infix macro indicate that it didn't want to handle the "$io.select" example? If it returns its input, unchanged, then that would be an infinite loop.
Dave. -- http://dave.whipp.name