(Ruby) Corrupted by JavaScript
I have been corrupted by JavaScript. Ruby really annoyed me when I could not just add properties and functions totally willy-nilly to instances. Ruby makes it easy to reopen classes, or even instances, but it is not so obvious how to do so without creating a new scope (and hence losing your closure).
The ~standared mechanism is to do something vicious like this:
foo = "hello"
msg = "woot!"
class<<foo; self; end.send(:attr_accessor, :bar)
class<<foo; self; end.send(:define_method, :woot) { puts msg }
foo.bar = 7
foo.woot # => "woot!"
Aside from the fact that this is a vicious hack, it relies on the
fact that send
lets you invoke private methods
(define_method
) on the singleton class (more recently
going by the alias of eigenclass) of foo
. This is pretty
much a bug and a violation of the object. It's like object rape, or
something.
A nicer way to do it, to my mind, is to use anonymous modules. The
really nice part of using anonymous modules is that the
Module
constructor takes a block which is evaluated in
the context of the new module, letting you legally call
private methods, like define_method
.
moo = "TOOW!"
foo.extend(Module.new { attr_accessor :baz })
foo.extend(Module.new { define_method(:toow) { puts moo }} )
foo.baz = 7
foo.toow # => "TOOW!"
moo = "MOOO!!"
foo.toow # => "MOOO!!"
This has the same effect and no nasty exploitation of the send bug!
Of course, with javascript, it is just...
foo = "woot"
foo.bar = 7
foo.stuff = function(a, b, c) { a * b * c }
I still like ruby more, though ;-)