Now, Ruby has a limited amount of operator overloading, but that is in most cases limited by what is predefined. There is actually a category of operators that are not available be the regular syntax, but that can still be created. I'm talking about almost all the regular single operators followed by either a plus sign or a minus sign.
Right now, I don't have a perfect example of where this is useful, but I guess someone will come up with it. You can use it in all cases where you want to be able to use stuff like binary ++, binary --, /-, *+, *-, %-, %+, %^, and so forth.
This trick makes use of the parsing of unary operators combined with binary operators. So, for example, this code:
module FixProxy; endwill actually output "Foo BAR Baz".
class String
def +@
extend FixProxy
end
alias __old_plus +
def +(val)
if val.kind_of?(FixProxy)
__old_plus(" BAR " << val)
else
__old_plus(val)
end
end
end
puts("Foo" ++ "Baz")
I'm pretty certain someone kind find a good use for it.
4 kommentarer:
You have to be a little more careful than that. Given your implementation above:
suffix = "suffix"
"foo" ++ suffix # => foo BAR suffix
"bar" + suffix # => foo BAR suffix
which probably isn't what you want.
def +@
dup.extend FixProxy
end
is probably safer, but if you need to call any mutators on suffix it won't quite behave correctly. In that case you'll need to turn your proxy into a decorator with slightly more complex behaviour.
But you knew that, I'm sure.
You are absolutely right. And no, I didn't think about this when I wrote the post, so thanks for the clarification. =)
I just wanted to say something about the concept. I'm not even sure I like it that much, especially since it will make things a little complicated in the real life, as you say.
It's the sort of thing I wouldn't ever want to see in the body of general ruby code.
However, it's an awfully useful technique when you're attempting to make a block scoped little language (RSpec's probably the best current example of what I mean).
It would be better to tweak the parser I would think.
Skicka en kommentar