Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

29 views
Skip to first unread message

Alexey Petrushin

unread,
Mar 6, 2011, 10:09:44 AM3/6/11
to
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.

--
Posted via http://www.ruby-forum.com/.

Sean O'Halpin

unread,
Mar 6, 2011, 10:49:16 AM3/6/11
to
On Sun, Mar 6, 2011 at 3:09 PM, Alexey Petrushin <axy...@gmail.com> 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

7stud --

unread,
Mar 6, 2011, 3:38:21 PM3/6/11
to
You can inherit from BlankSlate instead of BasicObject, which was
modeled after BlankSlate, and call YourClassName.reveal(:class) to
enable the class method.

7stud --

unread,
Mar 6, 2011, 4:21:06 PM3/6/11
to
..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.

7stud --

unread,
Mar 6, 2011, 4:33:16 PM3/6/11
to
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."

Michael Edgar

unread,
Mar 6, 2011, 5:26:45 PM3/6/11
to
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 Edgar
ad...@carboni.ca
http://carboni.ca/

On Mar 6, 2011, at 4:21 PM, 7stud -- wrote:

> ...or even simpler: just open up BasicObject and monkeypatch a class

Sean O'Halpin

unread,
Mar 6, 2011, 6:17:04 PM3/6/11
to
> 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

Sean O'Halpin

unread,
Mar 6, 2011, 6:26:28 PM3/6/11
to
On Sun, Mar 6, 2011 at 9:21 PM, 7stud -- <bbxx78...@yahoo.com> 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

Alexey Petrushin

unread,
Mar 6, 2011, 10:17:56 PM3/6/11
to
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 :)

0 new messages