Gregory Seidman
10/9/2007 2:30:00 PM
On Tue, Oct 09, 2007 at 01:10:07PM +0900, Jay Levitt wrote:
[...]
> What if class definitions were viewed through a magic prism, where only
> those classes looking from the right perspective saw the new extensions?
> Mind you, I have no idea how to partition the codespace in any sane manner
> - even from a design spec point-of-view. Should ActiveRecord see Og's
> extensions? Probably not; but ActionView and ActionPack might want to
> share. And what happens if Og passes a Hash to ActiveRecord that happens
> to include an Og-provided Time#today in it?
>
> I dunno. On the surface it seems that there must be some nicer way to add
> better locality of reference to core extensions, but I can't imagine how it
> would be implemented, how it should work, or if it would even be a good
> idea. Just some good old Sunday night musings.
>
> Do other languages do anything like that?
I know of no language that does anything like it. That said, there are good
reasons to want something like it. Actually, I have often wanted a
construct like this:
class SomeClass
module ExtraStuff
def my_extra_method
#...
end
end
def some_method(arg)
arg.let_extended(ExtraStuff) do |ext_arg|
ext_arg.my_extra_method
#...
end
end
end
If it isn't obvious, I want the equivalent of arg.extend(ExtraStuff) but
only within the scope of the block. Whatever my ExtraStuff module does, I
only want it mixed into an object for a brief scope. The simple solution
is:
#...
def some_method(arg)
ext_arg = arg.dup
ext_arg.extend(ExtraStuff)
ext_arg.my_extra_method
#...
end
#...
But that doesn't read quite as cleanly, and I would prefer a core language
construct that could do it efficiently (i.e. without an object copy).
Furthermore, the semantics are different in that if my_extra_method changes
the state of the object, the state of the object passed into the method
will actually changed when using the hypothetical core language construct,
but not when using an extended copy of that object.
There's been discussion before about unincluding modules, but it's always
been considered too complicated to implement (I think). For this construct,
however, it should be as simple as copying the object's eigenclass,
including the module (or modules, since the let_extended method should
really take an arbitrary number of modules) in the duplicate eigenclass,
and setting the object's eigenclass pointer to the duplicate for the scope
of the block. I speak of this with only a vague knowledge of how MRI deals
with eigenclasses, much less how any other implementation (e.g. JRuby or
Rubinius) does, so it may be messier than that.
Does anyone find this interesting enough to push for an RCR? I've never
done one, but if I get some positive feedback then I'll look into it.
> Jay Levitt |
--Greg