[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Detecting singletons

Lars Westergren

7/25/2007 10:45:00 AM

I have a fairly large and complex object graph of Value Objects created
by soap4r and used in a Rails application. The app, which used to work,
now gets
Exception `TypeError' at
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/transactions.rb:97
- singleton can't be dumped
all over the place and I have narrowed it down to Marshal.dump being
used by Rails.

I have aliased Marshal.dump so that I can inspect the objects passed
first, I thought that would be the fastest way to locate the problematic
object. My question is, how do I detect that an object is a singleton?
Should I test with "responds_to?" if the "new" method lacking or that
the "instance" method is there? Or is there an easier way?

Thanks in advance,
Lars

12 Answers

Vincent Bray

7/25/2007 11:19:00 AM

0

On 25/07/07, Lars Westergren <lars.westergren@ki.se> wrote:
> I have a fairly large and complex object graph of Value Objects created
> by soap4r and used in a Rails application. The app, which used to work,
> now gets
> Exception `TypeError' at
> /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/transactions.rb:97
> - singleton can't be dumped
> all over the place and I have narrowed it down to Marshal.dump being
> used by Rails.
>
> I have aliased Marshal.dump so that I can inspect the objects passed
> first, I thought that would be the fastest way to locate the problematic
> object. My question is, how do I detect that an object is a singleton?
> Should I test with "responds_to?" if the "new" method lacking or that
> the "instance" method is there? Or is there an easier way?

(first post to this list, so get some salt)

Singleton in this case probably means that the object you're trying to
marshal has a singleton method defined on it (maybe the wrong term.
whatever it's called when you do stuff like "def object.foo;
some_foo(); end".)

The reason it can't be dumped is likely that dumping the 'data' bits
of the object won't save the singleton method(s), so unmarshalling
would be incomplete.

--
noodl

Robert Klemme

7/25/2007 11:20:00 AM

0

2007/7/25, Lars Westergren <lars.westergren@ki.se>:
> I have a fairly large and complex object graph of Value Objects created
> by soap4r and used in a Rails application. The app, which used to work,
> now gets
> Exception `TypeError' at
> /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/transactions.rb:97
> - singleton can't be dumped
> all over the place and I have narrowed it down to Marshal.dump being
> used by Rails.
>
> I have aliased Marshal.dump so that I can inspect the objects passed
> first, I thought that would be the fastest way to locate the problematic
> object. My question is, how do I detect that an object is a singleton?
> Should I test with "responds_to?" if the "new" method lacking or that
> the "instance" method is there? Or is there an easier way?

If Singleton === obj
puts "it's a singleton!"
end

Kind regards

robert

Robert Dober

7/25/2007 11:26:00 AM

0

On 7/25/07, Lars Westergren <lars.westergren@ki.se> wrote:
> I have a fairly large and complex object graph of Value Objects created
> by soap4r and used in a Rails application. The app, which used to work,
> now gets
> Exception `TypeError' at
> /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/transactions.rb:97
> - singleton can't be dumped
> all over the place and I have narrowed it down to Marshal.dump being
> used by Rails.
>
> I have aliased Marshal.dump so that I can inspect the objects passed
> first, I thought that would be the fastest way to locate the problematic
> object. My question is, how do I detect that an object is a singleton?
> Should I test with "responds_to?" if the "new" method lacking or that
> the "instance" method is there? Or is there an easier way?
>
> Thanks in advance,
> Lars
>
>
The following should do the trick -- alas :(

class Class
def is_singleton?
! ancestors.include?( self ) rescue false
end
end

HTH
Robert

--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Robert Dober

7/25/2007 11:28:00 AM

0

gsub( "Class", "Object")

Robert Dober

7/25/2007 11:29:00 AM

0

require 'singleton'
> If Singleton === obj
> puts "it's a singleton!"
> end
>
> Kind regards
>
> robert
>
>
Excellent, did not know about this 1!

Robert


--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Robert Dober

7/25/2007 11:39:00 AM

0

On 7/25/07, Robert Dober <robert.dober@gmail.com> wrote:
Did I do something stupid?

694/194 > irb
irb(main):001:0> require 'singleton'
=> true
irb(main):002:0> s = "abc"
=> "abc"
irb(main):003:0> sing = class << s; self end
=> #<Class:#<String:0xb7d9eaec>>
irb(main):004:0> Singleton === s
=> false
irb(main):005:0> Singleton === sing
**********
=> false
**********
irb(main):006:0> puts "??????"
??????
=> nil
irb(main):007:0>
R.

Robert Klemme

7/25/2007 11:46:00 AM

0

2007/7/25, Robert Dober <robert.dober@gmail.com>:
> On 7/25/07, Robert Dober <robert.dober@gmail.com> wrote:
> Did I do something stupid?

No, you seem to be dragged into the confusion between singleton and
singleton. :-)

> 694/194 > irb
> irb(main):001:0> require 'singleton'
> => true
> irb(main):002:0> s = "abc"
> => "abc"
> irb(main):003:0> sing = class << s; self end
> => #<Class:#<String:0xb7d9eaec>>
> irb(main):004:0> Singleton === s
> => false
> irb(main):005:0> Singleton === sing
> **********
> => false
> **********
> irb(main):006:0> puts "??????"
> ??????
> => nil
> irb(main):007:0>

The "singleton" you are referring to is the singleton class (btw, now
I understand your code suggestion). I believe the OP wanted to know
about Singleton as in

class Foo
include Singleton
end

Kind regards

robert

Lars Westergren

7/25/2007 11:48:00 AM

0

Robert Dober skrev:
> On 7/25/07, Robert Dober <robert.dober@gmail.com> wrote:
> Did I do something stupid?
Oh, good, so it wasn't just me then.
:)

It doesn't seem to work for me either. I get false, and then the
exception anyway.

I think that test only works if the class in question used the Singleton
module mixin, I believe the problematic class probably uses some form of
sing = class << self; self end
magic.

I tried looking at the code for marshalling, but alas, it was C, and
therefore not much help to me...

if (FL_TEST(klass, FL_SINGLETON)) {
if (check && RCLASS(klass)->m_tbl->num_entries ||
(RCLASS(klass)->iv_tbl && RCLASS(klass)->iv_tbl->num_entries
> 1)) {
rb_raise(rb_eTypeError, "singleton can't be dumped");
}



Thanks,
Lars

Robert Klemme

7/25/2007 11:48:00 AM

0

2007/7/25, Robert Klemme <shortcutter@googlemail.com>:
> 2007/7/25, Robert Dober <robert.dober@gmail.com>:
> > On 7/25/07, Robert Dober <robert.dober@gmail.com> wrote:
> > Did I do something stupid?
>
> No, you seem to be dragged into the confusion between singleton and
> singleton. :-)

No, *I* confused them. Just forget all the rest of what I wrote.

Sorry for the noise. I should have checked.

Cheers

robert

Robert Dober

7/25/2007 11:57:00 AM

0

On 7/25/07, Lars Westergren <lars.westergren@ki.se> wrote:
well seems you have to use my code then, it depends on a "feature"
Matz has put deliberately into the implementation of ancestor,
singletons are not included.
Does this fit your definition of singleton?
Robert
>


--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck