Hi Kaspar,
So for your method (you might want to reconsider the name), you'd have
>
> def foo(sym)
> FooBind.new(symbol)
> end
>
> As long as FooBind quacks like a duck, you should be fine.
>
Oh cool, I'll definitely have a play with that.
>
> But I feel another library lurking in there: What if I could also match
> things inside classes that implement a matcher interface? Like:
>
> Tree.new(left, right)
>
> rule(Tree(some_left, some_right)) { ... }
>
> Yeah, that would be all kinds of useful. Can you get it done in the next
hour or so? ;)
> BTW: I guess you know that you can apply transformations in stages?
> Nothing prevents you from reinjecting the first transformation result
> into the second transformation.
>
Yes, been there. Somehow it felt wrong. I had a set of transforms for
building binary expression trees, and another for building parenthesised
expressions. Then I'd call the binary expression transform again to weld
together the parens expressions that it couldn't deal with the first time
around. Then I refactored my binary class to know about parentheses (and
switching to a subtree() match), and the whole thing collapsed into a nice
compact ball of loveliness.
Now I do this:
transforms = [ LiteralTransform, UnaryOperatorTransform,
BinaryOperatorTransform,
TernaryOperatorTransform, PostfixOperationTransform]
puts "PARSING '#{str}'"
puts "ORIGINAL TREE:"
ap tree
result = transforms.inject(tree) do |acc, n|
acc = n.new.apply(acc)
puts "\n\nTRANSFORMED BY #{n.to_s}"
ap acc
acc
end
which seems pretty lightweight to me. I split the transforms out into
separate blocks because I was having problems with them interfering with
each other; however I think this is because in the early stages I didn't
properly understand what was going on, and they could probably all be
amalgamated into one transform class.
BTW, the "ap" above is awesome_print, which is *insanely* useful when you're
trying to understand parslet's output.
ant