Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: About 1.9 #__method__ feature."
> on Tue, 4 Jul 2006 02:07:30 +0900, transfire / gmail.com writes:
>
> |No problem. I will try to paint better picture. I have variant of
> |OpenStruct called OpenObject:
> |
> | class OpenObject < BasicObject #(this is my BasicObject like
> |BlankSlate)
> | ...
> |
> |Using BasicObject as parent removes (almost) all kernel methods which
> |ensures no name clashes when using the OpenObject. Problem is sometimes
> |those removed methods are needed. So the important ones are available
> |by shadow methods, like __send__ even though #send is removed. Problem
> |is A) how many and which kernel methods should be shadowed; all of
> |them? and worse B) it means users have to be aware when a subclass of
> |BasicObject might be used and call the LCD, ie. shadow methods instead
> |of regular methods.
>
> I don't know what you expect for BasicObject and OpenObject.
> BasicObject is a BasicObject what it is. Could you describe what you
> want and what you expect first please? BasicObject may not be the
> answer for your problem. If it's not the right answer, tweaking it to
> adopt your requirement might not be a good idea.
OpenObject is just like OpenStruct, but it is faster and removes
methods that would get in thte way using BasicObject, for example
#class. More detailed example:
require 'facet/openobject'
require 'ostruct'
oo = OpenObject.new
os = OpenStruct.new
oo.class = "foo" #=> "foo"
os.class = "foo" #=> "foo"
oo.class #=> "foo"
os.class #=> "OpenStruct"
Also BasicObject can be useful for any class that uses method_missing
since it removes kernel methods that would not otherwise be missing.
> What does this __self__ do?
class BasicObject
# The Self class allows one to get access the hidden Object/Kernel
methods.
# It is essentially a specialized Functor which binds an
Object/Kernel
# method to the current object for the current call.
class Self < self
def initialize(obj, as=nil)
@obj = obj
@as = as || ::Object
end
def method_missing(meth, *args, &blk)
@as.instance_method(meth).bind(@obj).call(*args, &blk)
end
end
# Returns the Self functor class, which can then be used to
# call Kernel/Object methods on the current object.
def __self__
@__self__ ||= Self.new( self )
end
# This method is like #__self__, but allows any ancestor
# to act on behalf of self, not just Object.
def __as__( ancestor )
Self.new( self, ancestor )
end
> |What were the sticking points?
>
> Separating it would break Ruby's object model. It would make it much
> more complex at least, far more complex than I can bear.
>
> |I spent some time considering this and
> |arrived at a conception of layers, almost like subclassing, eg
> |MyClass:Public < MyClass:Private.
>
> ? Sorry, I don't get it.
Acutally I have that backward, sorry. MyClass:Private <
MyClass:Public.The idea beng that the public layer is like a superclass
to the private layer. Outside access is directed to the Public layer
and internal access directed to the Private layer. So clearly if a
method isn't in the private layer it goes back to the public layer.
Private layer could even call super to access public layer. So it's
like dividing a class inot two transparently cojoined classes.
T.