How to duplicate a object changing the class without attributesmemory copy

Discussion in 'Ruby' started by Iñaki Baz Castillo, Apr 11, 2008.

  1. SGksIEknbSBkb2luZyBhIHNlcnZlciBhbmQgd2FudCB0byBhdm9pZCBtZW1vcnkgaW5uZWNlc2Fy
    eSBvcGVyYXRpb25zLgpJIGhhdmUgYW4gYXJyYXkgb2YgaGVhZGVyczoKICBoZWFkZXJzX2FycmF5
    CgpFYWNoIGhlYWRlciBpcyBhbiBvYmplY3Qgb2YgIkhlYWRlciIgY2xhc3M6CgoJY2xhc3MgSGVh
    ZGVyCgkJYXR0cl9hY2Nlc3NvciA6bmFtZSwgOmJvZHkKCQlkZWYgaW5pdGlhbGl6ZShuYW1lLCBi
    b2R5KQoJCQlAbmFtZSA9IG5hbWUKCQkJQGJvZHkgPSBib2R5CgkJZW5kCgllbmQKCgpUaGVyZSBh
    cmUgYWxzbyBvdGhlcnMgc3BlY2lmaWMgaGVhZGVycyBzb29ucyBvZiAiSGVhZGVyIiBjbGFzczoK
    CgljbGFzcyBGcm9tIDwgSGVhZGVyCgkJYXR0cl9hY2Nlc3NvciA6dXJpCgllbmQKCgpBdCB0aGUg
    YmVnZ2luaW5nICJoZWFkZXJzX2FycmF5IiBqdXN0IGNvbnRhaW4gIkhlYWRlciIgb2JqZWN0cyBi
    dXQKYWZ0ZXIgaW5zcGVjdGlvbiBJIHdhbnQgdG8gcmVwbGFjZSB0aGUgaGVhZGVyIHdpdGggQG5h
    bWU9J0Zyb20nIHdpdGggYQoiRnJvbSIgb2JqZWN0IGJ1dCBzaW5jZSAibmFtZSIgYW5kICJib2R5
    IiBhdHRyaWJ1dGVzIGFyZSB0aGUgc2FtZSBJCmRvbid0IHdhbnQgYSBtZW1vcnkgY29weSBvcGVy
    YXRpb24gdG8gYWxsb2NhdGUgc3BhY2UgZm9yIG5ldyBvYmplY3QuCgpUaGlzIGlzOiBJIGp1c3Qg
    d2FudCB0byBjaGFuZ2UgdGhlIENsYXNzIG9mIGEgIkhlYWRlciIgb2JqZWN0IHRvCiJGcm9tIiBj
    bGFzcywga2VlcGluZyB0aGUgYXR0cmlidXRlcyB3aXRob3V0IG1lbW9yeSBjb3B5IG9wZXJhdGlv
    biwgaXMKdGhlcmUgYW55IHdheT8gSSBpbWFnaW5lIGluIEMgSSdkIGRvIGl0IGJ5IHVzaW5nIHBv
    aW50ZXJzLgoKClRoYW5rcyBmb3IgYW55IGhlbHAuCgoKCi0tIApJw7Fha2kgQmF6IENhc3RpbGxv
    CjxpYmNAYWxpYXgubmV0Pgo=
     
    Iñaki Baz Castillo, Apr 11, 2008
    #1
    1. Advertising

  2. Iñaki Baz Castillo wrote:
    > Hi, I'm doing a server and want to avoid memory innecesary operations.
    > I have an array of headers:
    > headers_array
    >
    > Each header is an object of "Header" class:
    >
    > class Header
    > attr_accessor :name, :body
    > def initialize(name, body)
    > @name = name
    > @body = body
    > end
    > end
    >
    >
    > There are also others specific headers soons of "Header" class:
    >
    > class From < Header
    > attr_accessor :uri
    > end
    >
    >
    > At the beggining "headers_array" just contain "Header" objects but
    > after inspection I want to replace the header with @name='From' with a
    > "From" object but since "name" and "body" attributes are the same I
    > don't want a memory copy operation to allocate space for new object.
    >
    > This is: I just want to change the Class of a "Header" object to
    > "From" class, keeping the attributes without memory copy operation, is
    > there any way? I imagine in C I'd do it by using pointers.


    Why do you need a From class that is distinct from Header? Depending on
    the reason, it might work to make From a module:

    module From
    # special From methods here
    end

    headers.each do |h|
    if h.name == "From"
    h.extend From
    end
    # or maybe something like:
    # h.extend const_get(h.name)
    end

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Apr 12, 2008
    #2
    1. Advertising

  3. MjAwOC80LzEyLCBKb2VsIFZhbmRlcldlcmYgPHZqb2VsQHBhdGguYmVya2VsZXkuZWR1PjoKCj4g
    IFdoeSBkbyB5b3UgbmVlZCBhIEZyb20gY2xhc3MgdGhhdCBpcyBkaXN0aW5jdCBmcm9tIEhlYWRl
    cj8KCkJlY2F1c2UgaW4gYW4gaW5pdGlhbCBwYXJzaW5nIEkganVzdCBnZXQgYSBoZWFkZXJzIGFy
    cmF5LCB3aGlvdHUKaW5zcGVjdGluZyBlYWNoIG9mIHRoZW0uCkxhdGVyLCBpZiBJIG5lZWQsIEkg
    bG9vayBmb3Igc29tZSBzcGVjaWZpYyBoZWFkZXJzIChGcm9tLCBUby4uLikgYW5kCm5lZWQgdG8g
    YWRkIHNvbWUgbWV0aG9kcyB0byB0aGVtLgoKCj4gRGVwZW5kaW5nIG9uIHRoZQo+IHJlYXNvbiwg
    aXQgbWlnaHQgd29yayB0byBtYWtlIEZyb20gYSBtb2R1bGU6Cj4KPiAgbW9kdWxlIEZyb20KPiAg
    ICMgc3BlY2lhbCBGcm9tIG1ldGhvZHMgaGVyZQo+ICBlbmQKPgo+ICBoZWFkZXJzLmVhY2ggZG8g
    fGh8Cj4gICBpZiBoLm5hbWUgPT0gIkZyb20iCj4gICAgIGguZXh0ZW5kIEZyb20KPiAgIGVuZAo+
    ICAgIyBvciBtYXliZSBzb21ldGhpbmcgbGlrZToKPiAgICMgaC5leHRlbmQgY29uc3RfZ2V0KGgu
    bmFtZSkKPiAgZW5kCgpUaGFua3MsIHRoaXMgaXMgZ3JlYXQhIEkgZGlkbid0IGtub3cgImV4dGVu
    ZCIgbWV0aG9kLgoKCi0tIApJw7Fha2kgQmF6IENhc3RpbGxvCjxpYmNAYWxpYXgubmV0Pgo=
     
    Iñaki Baz Castillo, Apr 12, 2008
    #3
  4. 2008/4/12, I=F1aki Baz Castillo <>:
    > 2008/4/12, Joel VanderWerf <>:
    >
    >
    > > Why do you need a From class that is distinct from Header?

    >
    >
    > Because in an initial parsing I just get a headers array, whiotu
    > inspecting each of them.
    > Later, if I need, I look for some specific headers (From, To...) and
    > need to add some methods to them.


    IMHO it is more efficient and less error prone if you create
    appropriate instances during initial parsing. You have all the
    information at that point in time plus you you save one additional
    pass through the collection.

    > > Depending on the
    > > reason, it might work to make From a module:
    > >
    > > module From
    > > # special From methods here
    > > end
    > >
    > > headers.each do |h|
    > > if h.name =3D=3D "From"
    > > h.extend From
    > > end
    > > # or maybe something like:
    > > # h.extend const_get(h.name)
    > > end

    >
    >
    > Thanks, this is great! I didn't know "extend" method.


    Well, you can even do it during construction:

    class Header
    attr_accessor :name, :body
    def initialize(name, body)
    @name =3D name
    @body =3D body
    extend From if /From/ =3D~ name
    end
    end

    But I'd rather leave the decision to the parsing code.

    Cheers

    robert

    --=20
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Apr 14, 2008
    #4
  5. El Lunes, 14 de Abril de 2008, Robert Klemme escribi=F3:
    > 2008/4/12, I=F1aki Baz Castillo <>:
    > > 2008/4/12, Joel VanderWerf <>:
    > > > Why do you need a From class that is distinct from Header?

    > >
    > > Because in an initial parsing I just get a headers array, whiotu
    > > inspecting each of them.
    > > Later, if I need, I look for some specific headers (From, To...) and
    > > need to add some methods to them.

    >
    > IMHO it is more efficient and less error prone if you create
    > appropriate instances during initial parsing. You have all the
    > information at that point in time plus you you save one additional
    > pass through the collection.


    Yes, but let me explain:

    I'm doing a SIP protocol parser. In SIP a repeated request can be received=
    =20
    because retransmissions and there is no need at all of parsing the entire=20
    request to know if it's a retransmission (since it will be discarded).
    Also, I don't need to parse all the headers, but I cannot know which header=
    s=20
    I'll need to parse since that is a application layer decission instead of=20
    transport layer decission.
    =46or example: If I implement a SIp proxy I just need to parse some headers=
    , if=20
    I do a SIP server UAS I need to parse others. Transport layer is common but=
    =20
    application layer not, so I don't need to do all the parsing in transport=20
    layer.




    Thanks a lot for all you suggestions and help. Best regards.


    =2D-=20
    I=F1aki Baz Castillo
     
    Iñaki Baz Castillo, Apr 14, 2008
    #5
  6. Iñaki Baz Castillo

    Gary Wright Guest

    On Apr 11, 2008, at 7:41 AM, I=F1aki Baz Castillo wrote:
    >
    > At the beggining "headers_array" just contain "Header" objects but
    > after inspection I want to replace the header with @name=3D'From' with =

    a
    > "From" object but since "name" and "body" attributes are the same I
    > don't want a memory copy operation to allocate space for new object.
    >
    > This is: I just want to change the Class of a "Header" object to
    > "From" class, keeping the attributes without memory copy operation, is
    > there any way? I imagine in C I'd do it by using pointers.


    You can not change the class of an object in Ruby.

    You'll have to instantiate a new object and copy the
    attributes. If you just do something like:

    from_obj.name =3D header_obj.name

    You are simply copying object references, you aren't
    copying all the associated data.

    Gary Wright=
     
    Gary Wright, Apr 14, 2008
    #6
  7. El Lunes, 14 de Abril de 2008, Gary Wright escribi=F3:
    > =A0If you just do something like:
    >
    > from_obj.name =3D header_obj.name
    >
    > You are simply copying object references, you aren't
    > copying all the associated data.


    Hi, that's not true: if an attribute is a String then there will be memory=
    =20
    copy:

    class Header
    attr_accessor :name
    end

    class From
    attr_accessor :name
    end

    header =3D Header.new
    header.name =3D "AAAA"
    =3D> "AAAA"

    from =3D From.new
    from.name =3D header.name
    =3D> "AAAA"

    from.name =3D "BBBB"
    =3D> "BBBB"

    header.name
    =3D> "AAAA"


    As you see in the example above if the attribute is a String (or a Fixnum a=
    nd=20
    so) attribute copy means memory dupplication. Unfortunatelly in my case the=
    =20
    attribute is a String.

    Regards.





    =2D-=20
    I=F1aki Baz Castillo
     
    Iñaki Baz Castillo, Apr 15, 2008
    #7
  8. Re: How to duplicate a object changing the class without attributes memory copy

    I=F1aki Baz Castillo wrote:
    > El Lunes, 14 de Abril de 2008, Gary Wright escribi=F3:
    >> If you just do something like:
    >>
    >> from_obj.name =3D header_obj.name
    >>
    >> You are simply copying object references, you aren't
    >> copying all the associated data.

    >
    > Hi, that's not true: if an attribute is a String then there will be
    > memory copy:
    >
    > class Header
    > attr_accessor :name
    > end
    >
    > class From
    > attr_accessor :name
    > end
    >
    > header =3D Header.new
    > header.name =3D "AAAA"
    > =3D> "AAAA"
    >
    > from =3D From.new
    > from.name =3D header.name
    > =3D> "AAAA"
    >
    > from.name =3D "BBBB"
    > =3D> "BBBB"
    >
    > header.name
    > =3D> "AAAA"
    >
    >
    > As you see in the example above if the attribute is a String (or a
    > Fixnum and so) attribute copy means memory dupplication.
    > Unfortunatelly in my case the attribute is a String.
    >
    > Regards.


    Not true. To verify it, after you do "from.name =3D header.name", try this:

    puts header.name.object_id
    puts from.name.object_id

    You will see same object id, meaning that you have a reference, not a new o=
    bject. To make it a copy, do this:

    from.name =3D header.name.dup

    Gennady.
     
    Gennady Bystritsky, Apr 15, 2008
    #8
  9. Re: How to duplicate a object changing the class without attributes memory copy

    MjAwOC80LzE1LCBHZW5uYWR5IEJ5c3RyaXRza3kgPEdlbm5hZHkuQnlzdHJpdHNreUBxdWVzdC5j
    b20+Ogo+IE5vdCB0cnVlLiBUbyB2ZXJpZnkgaXQsIGFmdGVyIHlvdSBkbyAiZnJvbS5uYW1lID0g
    aGVhZGVyLm5hbWUiLCB0cnkgdGhpczoKPgo+ICBwdXRzIGhlYWRlci5uYW1lLm9iamVjdF9pZAo+
    ICBwdXRzIGZyb20ubmFtZS5vYmplY3RfaWQKPgo+ICBZb3Ugd2lsbCBzZWUgc2FtZSBvYmplY3Qg
    aWQsIG1lYW5pbmcgdGhhdCB5b3UgaGF2ZSBhIHJlZmVyZW5jZSwgbm90IGEgbmV3IG9iamVjdC4K
    Ck9oaCwgdGhhdCdzIGFubm95aW5nIGZvciBtZSEKWW91IGFyZSByaWdodCwgYm90aCBhcmUgdGhl
    IHNhbWUgb2JqZWN0cyAqKnVudGlsKiogSSBtb2RpZnkgb25lIG9mIHRoZW0uIEkgbWVhbjoKCiAg
    ZnJvbS5uYW1lID0gaGVhZGVyLm5hbWUKICA9PiAiQUFBQSIKICBmcm9tLm5hbWUuIG9iamVjdF9p
    ZCA9PSBoZWFkZXIubmFtZS5vYmplY3RfaWQKICA9PiB0cnVlCgpTbyBpbiB0aGlzIG1vbWVudCBm
    cm9tLm5hbWUuIG9iamVjdF9pZCA9PSBoZWFkZXIubmFtZS5vYmplY3RfaWQuIEJ1dAppZiBJIGNo
    YW5nZSB0aGUgdmFsdWU6CgogIGZyb20ubmFtZSA9ICJCQkJCIgogIGZyb20ubmFtZS4gb2JqZWN0
    X2lkID09IGhlYWRlci5uYW1lLm9iamVjdF9pZAogID0+IGZhbHNlCgpUaGVuIGZyb20ubmFtZS4g
    b2JqZWN0X2lkICE9IGhlYWRlci5uYW1lLm9iamVjdF9pZCwgc28gdGhlbiB0aGVyZSBhcmUKdHdv
    IHZhbHVlcyBpbiBtZW1vcnkgYXQgc2FtZSB0aW1lLgoKUmVnYXJkcy4KCgotLSAKScOxYWtpIEJh
    eiBDYXN0aWxsbwo8aWJjQGFsaWF4Lm5ldD4K
     
    Iñaki Baz Castillo, Apr 15, 2008
    #9
  10. On Tue, Apr 15, 2008 at 10:26 AM, I=F1aki Baz Castillo <> wrot=
    e:
    > 2008/4/15, Gennady Bystritsky <>:
    >
    > > Not true. To verify it, after you do "from.name =3D header.name", try t=

    his:
    > >
    > > puts header.name.object_id
    > > puts from.name.object_id
    > >
    > > You will see same object id, meaning that you have a reference, not a=

    new object.
    >
    > Ohh, that's annoying for me!
    > You are right, both are the same objects **until** I modify one of them.=

    I mean:

    This sentence is confusing: you don't modify one of them, you assign
    the variable
    a different object:

    a =3D "header"
    b =3D a

    a --------> "header"
    ^
    |
    |
    b


    b =3D "new header"

    a --------> "header"
    b --------> "new header"

    The object previously referenced by both a and b has not been modified.
    When you assigned a new string to b, then b referenced a different object.

    Jesus.
     
    Jesús Gabriel y Galán, Apr 15, 2008
    #10
  11. Re: How to duplicate a object changing the class without attributes memory copy

    I=F1aki Baz Castillo wrote:
    > 2008/4/15, Gennady Bystritsky <>:
    >> Not true. To verify it, after you do "from.name =3D header.name", try
    >> this:
    >>
    >> puts header.name.object_id
    >> puts from.name.object_id
    >>
    >> You will see same object id, meaning that you have a reference, not
    >> a new object.

    >
    > Ohh, that's annoying for me!
    > You are right, both are the same objects **until** I modify
    > one of them. I mean:
    >
    > from.name =3D header.name
    > =3D> "AAAA"
    > from.name. object_id =3D=3D header.name.object_id
    > =3D> true
    >
    > So in this moment from.name. object_id =3D=3D header.name.object_id. But
    > if I change the value:
    >
    > from.name =3D "BBBB"
    > from.name. object_id =3D=3D header.name.object_id
    > =3D> false
    >
    > Then from.name. object_id !=3D header.name.object_id, so then there are
    > two values in memory at same time.
    >
    > Regards.


    You do not change the value, you just assign a reference to a new string. T=
    o change the content of a string object you need to use replace() on it. It=
    looks like it omits you that "AAAA" and "BBBB" make string objects already=
    and not just when you assign them to a variable.

    Gennady.
     
    Gennady Bystritsky, Apr 15, 2008
    #11
  12. Re: How to duplicate a object changing the class without attributes memory copy

    MjAwOC80LzE1LCBHZW5uYWR5IEJ5c3RyaXRza3kgPEdlbm5hZHkuQnlzdHJpdHNreUBxdWVzdC5j
    b20+OgoKPiBZb3UgZG8gbm90IGNoYW5nZSB0aGUgdmFsdWUsIHlvdSBqdXN0IGFzc2lnbiBhIHJl
    ZmVyZW5jZSB0byBhIG5ldyBzdHJpbmcuIFRvIGNoYW5nZSB0aGUgY29udGVudCBvZiBhIHN0cmlu
    ZyBvYmplY3QgeW91IG5lZWQgdG8gdXNlIHJlcGxhY2UoKSBvbiBpdC4gSXQgbG9va3MgbGlrZSBp
    dCBvbWl0cyB5b3UgdGhhdCAiQUFBQSIgYW5kICJCQkJCIiBtYWtlIHN0cmluZyBvYmplY3RzIGFs
    cmVhZHkgYW5kIG5vdCBqdXN0IHdoZW4geW91IGFzc2lnbiB0aGVtIHRvIGEgdmFyaWFibGUuCgpU
    aGFua3MgdG8gYm90aCwgSSd2ZSB1bmRlcnN0b29kIG5vdzoKCmE9IkFBQUEiCj0+ICJBQUFBIgoK
    YS5vYmplY3RfaWQKPT4gLTYwNjA1NjEzOAoKYT0iQkJCQiIKPT4gIkJCQkIiCgphLm9iamVjdF9p
    ZAo9PiAtNjA2MDYzNDk4CgoKVGhhbmtzIDopCgoKLS0gCknDsWFraSBCYXogQ2FzdGlsbG8KPGli
    Y0BhbGlheC5uZXQ+Cg==
     
    Iñaki Baz Castillo, Apr 15, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jesper Sahner
    Replies:
    4
    Views:
    502
    Boudewijn Dijkstra
    Jan 18, 2005
  2. Alex
    Replies:
    2
    Views:
    1,243
  3. Replies:
    26
    Views:
    2,129
    Roland Pibinger
    Sep 1, 2006
  4. Aaron Beall
    Replies:
    2
    Views:
    1,829
    Aaron Beall
    Sep 14, 2007
  5. Jason Lillywhite
    Replies:
    3
    Views:
    123
    Abhi Yerra
    Jan 16, 2009
Loading...

Share This Page