[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Duping a class causes error

Trans

1/27/2005 1:36:00 PM

Maybe someone can offer me a possible reason for this. I have a set of
classes in a module called Markers. I have a module method,
Markers#list, that does nothing more than collects them into an array.
Then in my program when I do:

| markers = Markers.list

It works. But when I do:

| markers = Markers.list.collect { |m| nm = m.dup ; nm }

It does not work.

I don't understand why. Obviously my initial thought is that something
about my Marker classes must not be shallow, but they're just classes,
made of methods and have no state, so I don't see how that can be.
(Actually they do have a small bit of boolean state in a class instance
var, but I check and it is being duplicated.)
I just don't get it. Any ideas?

Thanks,
T.

21 Answers

Robert Klemme

1/27/2005 1:48:00 PM

0


"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106832987.976217.139210@f14g2000cwb.googlegroups.com...
> Maybe someone can offer me a possible reason for this. I have a set of
> classes in a module called Markers. I have a module method,
> Markers#list, that does nothing more than collects them into an array.
> Then in my program when I do:
>
> | markers = Markers.list
>
> It works. But when I do:
>
> | markers = Markers.list.collect { |m| nm = m.dup ; nm }

You can also do:

markers = Markers.list.collect { |m| m.dup }

> It does not work.
>
> I don't understand why. Obviously my initial thought is that something
> about my Marker classes must not be shallow, but they're just classes,
> made of methods and have no state, so I don't see how that can be.

So Markers.list returns a list of class objects?

> (Actually they do have a small bit of boolean state in a class instance
> var, but I check and it is being duplicated.)
> I just don't get it. Any ideas?

What exactly goes wrong?

robert

Trans

1/27/2005 2:28:00 PM

0


Robert Klemme wrote:
> "Trans" <transfire@gmail.com> schrieb im Newsbeitrag
> news:1106832987.976217.139210@f14g2000cwb.googlegroups.com...
> > Maybe someone can offer me a possible reason for this. I have a set
of
> > classes in a module called Markers. I have a module method,
> > Markers#list, that does nothing more than collects them into an
array.
> > Then in my program when I do:
> >
> > | markers = Markers.list
> >
> > It works. But when I do:
> >
> > | markers = Markers.list.collect { |m| nm = m.dup ; nm }
>
> You can also do:
>
> markers = Markers.list.collect { |m| m.dup }

Thanks. That true, but the line I ultimately want is:

| markers = Markers.list.collect { |m| nm = m.dup ; nm.parser = self;
nm }

I need to pass the current parser object down to the markers themselves
b/c I do "reentrant" pasrsing. But obviously I don't want to effect the
Classes themselves with this state info in case they are used by
another parser, so I'm duplicating them.

> > It does not work.
> >
> > I don't understand why. Obviously my initial thought is that
something
> > about my Marker classes must not be shallow, but they're just
classes,
> > made of methods and have no state, so I don't see how that can be.
>
> So Markers.list returns a list of class objects?

Yes. Here, Markers.list returns

[MarkUps::Markers::Command, MarkUps::Markers::Verbatim,
MarkUps::Markers::Outline, MarkUps::Markers::Document,
MarkUps::Markers::Paragraph, MarkUps::Markers::Table]

and the dup'd collection returns:

[#<Class:0x4033a584>, #<Class:0x4033a534>, #<Class:0x4033a4f8>,
#<Class:0x4033a4a8>, #<Class:0x4033a480>, #<Class:0x4033a444>]

> > (Actually they do have a small bit of boolean state in a class
instance
> > var, but I check and it is being duplicated.)
> > I just don't get it. Any ideas?
>
> What exactly goes wrong?

Unfortunately it is strange. The Outline Marker which tells the parser
how to identify and parse an outline fails.

T.

Trans

1/27/2005 2:33:00 PM

0

Up. I figured it out.

And take a wild guess what the problem was! There's a riddle for you:
What gets lost when you copy a class to a variable?
Ex-
|
| x = String.dup
|

Answer coming up....

Trans

1/27/2005 3:11:00 PM

0

No stabs? Okay well the answer is: the name.
x = String.dup
p x.name
=> ""

T.

Robert Klemme

1/27/2005 3:12:00 PM

0


"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106836381.414471.268130@c13g2000cwb.googlegroups.com...
> Up. I figured it out.
>
> And take a wild guess what the problem was! There's a riddle for you:
> What gets lost when you copy a class to a variable?
> Ex-
> |
> | x = String.dup
> |
>
> Answer coming up....

The name

robert

Trans

1/27/2005 4:00:00 PM

0

Correct!

Unfortunately you were a minute late on the buzzer so we can only off
you the consolation prize --a virtual pat on the back. "pat, pat" :-)

But seriously, thanks robert, your questioning spurred me to dig in and
find the problem. And its a good thing to remember!

T.

Robert Klemme

1/27/2005 4:07:00 PM

0


"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106841626.063762.97840@f14g2000cwb.googlegroups.com...
> Correct!

Yippieh!

> Unfortunately you were a minute late on the buzzer so we can only off
> you the consolation prize --a virtual pat on the back. "pat, pat" :-)

Darn...

> But seriously, thanks robert, your questioning spurred me to dig in and
> find the problem. And its a good thing to remember!

Glad I could help. Btw, why is it that you dup classes? It seems strange
to me and there might some dangers, especially if those classes to be
duped refer each other:

>> class Foo; end
=> nil
>> class Bar; XX = Foo; end
=> Foo
>> Bar::XX
=> Foo
>> Bar::XX == Foo
=> true
>> bd = Bar.dup
=> #<Class:0x10181848>
>> bd::XX
=> Foo
>> bd::XX == Foo
=> true
>> class Box; def test() Foo; end end
=> nil
>> Box.new.test
=> Foo
>> Box.dup.new.test

Even Marshal doesn't help:

=> Foo>> Marshal::load(Marshal::dump(Box)).new.test == Foo
=> true
>> Marshal::load(Marshal::dump(Bar))::XX == Foo
=> true

Kind regards

robert

Trans

1/27/2005 4:27:00 PM

0

Good point. Fortunately these classes are all self contained beyond
being subclasses of Marker.

The reason has to do with some trouble I alsways seem to run into with
these types of apps. Basically I have a Parser instance that gets fed
Token classes (Markers) which contain class level information on how to
recognize the relavent text they will parse. Here a very simple
example:

require 'yaml'

s = "[test]THIS IS A [b]TEST[b.]&tm;[test.]"

class XmlTagToken < Parser::Token
normal!
def self.start( match ) ; %r{ \[ (.*?) \] }mx ; end
def self.stop( match ) ; %r{ \[ [ ]* (#{Regexp.escape(match[1])})
(.*?) \. \] }mx ; end
end

class XmlEntityToken < Parser::Token
unit!
def self.start( match ) ; %r{ \& (.*?) \; }x ; end
end

registry = Parser::Registry.new
registry.register( XmlTagToken )
registry.register( XmlEntityToken )

cp = Parser.new( registry )
d = cp.parse( s )
y d

The I take this further and add instance methods to the tokens to parse
sepecialize content. Sometimes that content is "reentrant", that is to
say I need to reparse it --like an embedded document.

So the problem? How do I talk to my Parser instance from within an
instance of a Token?

If you have an elgant solution to that I'll give you more than a pat on
the back!

T.

Hugh Sasse

1/27/2005 4:57:00 PM

0

Trans

1/27/2005 5:09:00 PM

0

> I have run into this problem myself, and have not seen a good
> solutoin to it. I have a suspicion that it probably means the
> separation of the two classes, in this case Parser and Token,
> is an incorrect model, because they both need access to each
> other.

Hmm... I'm not sure how that can be outside of through OOP out the
window. If I combine the Token and the Parser into a single thing then
that will really be the only thing there is ;-)

I'll think on it some more though.
I take it you've looked at parser.rb then?

T.