From: Caleb Clausen on
On 4/25/10, Mooffie n/a <mooffie(a)gmail.com> wrote:
> How, for example, can you find an object's class using pure Ruby?
>
> The problem with Ruby's #class is that it skips singletons. Example:
>
> s = "blah"
> def s.whatever; 666; end
> p s.class
>
> The above will print "String", but it's an error: the class should be
> some singleton.
>
> (Doing "class << s; self; end" isn't a solution because it alters the
> object model: it *creates* a singleton if none yet exists.)
>
> Though maybe there *is* a way to find an object's class, I don't know (I
> still consider myself a Ruby newbie).

I had thought that I had proved to myself that class<<s; self; end was
guaranteed to be nondestructive on all modern (>=1.8.6) versions of
ruby.... maybe not, tho. I'm not sure now. I might need to change some
of my own code in light of this....

Your terminology is a bit wrong, or at any rate unorthodox.
Object#class works as it was designed. In the above snippet, the class
of s is always a string, even tho its singleton class changes. The
#class of an object is its birth type, even tho the type can change
subsequently. (The klass field of an object doesn't always point
directly to an object's class... klass is kind of misnamed, actually.)

Recent vintages of 1.9 are supposed to have Object#singleton_class.

From: David Masover on
On Sunday 25 April 2010 02:41:07 am Charles Oliver Nutter wrote:
> On Sat, Apr 24, 2010 at 10:38 AM, David Masover <ninja(a)slaphack.com> wrote:
> >> For getting the data, you don't even need to write an extension to
> >> JRuby. The "jruby" library gives you introspective access to all
> >> objects at a very direct level:
> >
> > It seems like this should be possible to do from bare Ruby, in a portable
> > way. Clumsy, but possible. For example, as long as people don't get smart
> > and use Ruby 1.9's BasicObject, you can do this:
>
> No, I'm pretty sure this isn't possible on regular Ruby.

Ah, wishful thinking of my part, then.

> What's
> happening in JRuby is that you're getting direct access to the Java
> object representing a Ruby class or object, and you then can do
> anything to that object you'd normally have to write Java code for.

I've raised this question before, and people seem to disagree with me, but:

> # changing the object's class(!?)
> class Foo; end
> p obj.class # => 'Object'
> obj_ref.setMetaClass(JRuby.reference(Foo))
> p obj.class # => 'Foo'

I think it should be possible to do that from within Ruby.

But I can't even get most people behind this suggestion:

class A; end
class B; end
A.instance_method(:to_s).bind(B.new)

That gives me a type error, which just seems bizarre, especially after the
relative freedom of JavaScript. Ah, well.

From: Charles Oliver Nutter on
On Sun, Apr 25, 2010 at 3:23 PM, David Masover <ninja(a)slaphack.com> wrote:
> On Sunday 25 April 2010 02:41:07 am Charles Oliver Nutter wrote:
> I've raised this question before, and people seem to disagree with me, but:
>
>> # changing the object's class(!?)
>> class Foo; end
>> p obj.class # => 'Object'
>> obj_ref.setMetaClass(JRuby.reference(Foo))
>> p obj.class # => 'Foo'
>
> I think it should be possible to do that from within Ruby.
>
> But I can't even get most people behind this suggestion:
>
> class A; end
> class B; end
> A.instance_method(:to_s).bind(B.new)
>
> That gives me a type error, which just seems bizarre, especially after the
> relative freedom of JavaScript. Ah, well.

The main issue that comes up with this is that classes with native
methods (like all the core classes) would have to be given special
treatment. You couldn't, for example, rebind a String method to Array
or an Array subclass since the in-memory structure is different. In
short, you'd at best end up with methods that don't function because
they're not attached to an array, and at worst with methods that
outright segfault.

There's no technical reason you couldn't allow rebinding of Ruby
methods though. That's roughly possible in JRuby if you go "under the
covers":

require 'jruby'

class Foo
def foo
puts "This is foo in #{self.class}"
end
end

class Bar
end

foo_ref = JRuby.reference(Foo)
bar_ref = JRuby.reference(Bar)

bar_ref.add_method('bar', foo_ref.search_method('foo'))

Bar.new.bar # => "This is foo in Bar"

...of course, the devil's in the details.

- Charlie

From: David Masover on
On Monday 26 April 2010 10:04:04 am Charles Oliver Nutter wrote:
> On Sun, Apr 25, 2010 at 3:23 PM, David Masover <ninja(a)slaphack.com> wrote:
> > On Sunday 25 April 2010 02:41:07 am Charles Oliver Nutter wrote:
> >
> > I've raised this question before, and people seem to disagree with me,
but:
> >> # changing the object's class(!?)
> >> class Foo; end
> >> p obj.class # => 'Object'
> >> obj_ref.setMetaClass(JRuby.reference(Foo))
> >> p obj.class # => 'Foo'
> >
> > I think it should be possible to do that from within Ruby.
> >
> > But I can't even get most people behind this suggestion:
> >
> > class A; end
> > class B; end
> > A.instance_method(:to_s).bind(B.new)
> >
> > That gives me a type error, which just seems bizarre, especially after
> > the relative freedom of JavaScript. Ah, well.
>
> The main issue that comes up with this is that classes with native
> methods (like all the core classes) would have to be given special
> treatment. You couldn't, for example, rebind a String method to Array
> or an Array subclass since the in-memory structure is different. In
> short, you'd at best end up with methods that don't function because
> they're not attached to an array, and at worst with methods that
> outright segfault.

I think I'm OK with that. JavaScript doesn't allow rebinding native methods,
either. I would, however, strongly encourage fewer native methods when
possible -- doesn't Kernel#autoload _still_ use a native call to the native
require, thus bypassing any attempt to overload Kernel#require?

> There's no technical reason you couldn't allow rebinding of Ruby
> methods though.

Just a political one, I think. Every time I bring this up, I get a weak
justification that seems to be based around some desire for strong, static
typing, and strict, rigid inheritance.

It's especially frustrating when, as in my example above, I'm trying to rebind
a method which was originally declared on a parent class to both methods.
Having to figure out (or programmatically navigate!) the class hierarchy to
find the exact point which is a superclass (or supermodule) of both objects
I'm working with, yet still has the appropriate method, and then rebind it all
the way down the hierarchy, rather than at least having it Just Work
(A.instance_method(:to_s) should return Object#to_s unless I actually define
A#to_s), is the exact POLAR OPPOSITE of duck typing, do-what-I-mean, beautiful
code, and everything Ruby is supposed to be about. Let me decide if the class
is important -- if I really care, I can check obj.kind_of?(umeth.owner), but
there's no good reason for the language to make that decision for me! Ruby is
not supposed to be like Java!

*deep breaths*

I can definitely think of a few places where this would be useful. I can
probably hack around it anyway, though -- it mostly just offends the purist in
me. It is, IMO, the ugliest thing about Ruby's otherwise-beautiful object
model.

> That's roughly possible in JRuby if you go "under the
> covers"
[snip]
> ...of course, the devil's in the details.

As much as I like JRuby, I'd much prefer a portable solution. However, I
needed this for a project I've all but abandoned, so I'm not particularly
motivated to write such a solution. (I'd guess the closest I would get is a
single gem that does different hacks in different interpreters.)

From: Evgeniy Dolzhenko on
This little gem does what you want (with some magic from some very thin
native extension) http://github.com/oggy/looksee

Mooffie n/a wrote:
> How, for example, can you find an object's class using pure Ruby?
>
> The problem with Ruby's #class is that it skips singletons. Example:
>
> s = "blah"
> def s.whatever; 666; end
> p s.class
>
> The above will print "String", but it's an error: the class should be
> some singleton.
--
Posted via http://www.ruby-forum.com/.

First  |  Prev  | 
Pages: 1 2 3 4 5 6
Prev: [BUG] Segmentation fault
Next: ya config file parser