How to get class of BasicObject ancestor (Ruby 1.9.2)?

There’s no :class method on BasicObject, is there any way to get class
of it’s ancestors?

class SomeUtilityClassBase < BasicObject
def clone
clone = self.class.new # <= problem here, there’s no way to get
:class

return clone
end
end

class Config < SomeUtilityClassBase
end

a = Config.new
b = a.clone

Thanks.

On Sun, Mar 6, 2011 at 3:09 PM, Alexey P. [email protected]
wrote:

There’s no :class method on BasicObject, is there any way to get class
of it’s ancestors?

Here’s one way:

module DefineClass
def self.included(other)
other.class_eval {
define_method :class do
other
end
}
end
end

class SO < BasicObject
include ::DefineClass

@@counter = 0
def initialize(*a, &b)
super
@@counter += 1
end

def clone
clone = self.class.new
end

def inspect
“<#{self.class}: #{@@counter}>”
end
end

s = SO.new
p s.clone

=> <SO: 2>

(I’m not a huge fan of @@class_variables in general - it’s just here
to make the point that there are two different instances.)

Regards,
Sean

If you inherit from BlankSlate instead of BasicObject. The advantage
of doing that is that BlankSlate has a class method called reveal(),
which you can use to incrementally roll back your BlankSlate. In your
case, you would call YourClassName.reveal(:class) to
enable the class method.

Or, you could open up Object and undefine all the methods except the
ones in BasicObject plus :class.

7stud – wrote in post #985807:

If you inherit from BlankSlate instead of BasicObject. The advantage
of doing that is that BlankSlate has a class method called reveal(),
which you can use to incrementally roll back your BlankSlate. In your
case, you would call YourClassName.reveal(:class) to
enable the class method.

That last line should be:

“enable the :class instance method”

and the first line should read:

“You can inherit from BlankSlate instead of BasicObject.”

BasicObject as a singleton already has the class method (and it returns
Class, as expected).
You meant to suggest something like this:

class BasicObject
def class
BasicObject
end
end

But that would make any subclass of BasicObject that doesn’t override
this #class definition
would return BasicObject, which would be odd. I’m not sure of a
pure-ruby way to write #class,
it’s definitely written in C for the Object class.

Michael E.
[email protected]
http://carboni.ca/

I’m not sure of a pure-ruby way to write #class,
it’s definitely written in C for the Object class.

Here’s another attempt (this time handling inheritance):

module DefineClass
def self.define_class(klass)
klass.class_eval {
define_method :class do
klass
end
}
end
def self.extended(other)
define_class(other)
end
def inherited(other)
DefineClass.define_class(other)
end
end

class SO < BasicObject
extend ::DefineClass

@@counter = 0
def initialize(*a, &b)
super
@@counter += 1
end

def clone
clone = self.class.new
end

def inspect
“<#{self.class}: #{@@counter}>”
end
end

s = SO.new
p s.clone

=> <SO: 2>

class BO < SO
end

b = BO.new
p b.clone

=> <BO: 4>

Regards,
Sean

On Sun, Mar 6, 2011 at 9:21 PM, 7stud – [email protected] wrote:

…or even simpler: just open up BasicObject and monkeypatch a class
method called class(untested):
!
class BasicObject
def self.class
self
end
end

Then have at it.

You’ve changed the #class method of the BasicObject /class/, not the
/instance/.
So BasicObject.class will now return BasicObject (rather than Class)
and BasicObject.new.class will not work.

Regards,
Sean

Thanks for advices, good news for me is that I have small amount of
ancestors, so for now I just hardcoded it’s class names.

In my case using :inherited callback magic is too over engineered
solution :slight_smile: