Prev: [BUG] Segmentation fault
Next: ya config file parser
From: Caleb Clausen on 25 Apr 2010 11:14 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 25 Apr 2010 16:23 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 26 Apr 2010 11:04 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 27 Apr 2010 23:50 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 1 May 2010 12:31
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/. |