How to duplicate a object changing the class without attributesmemory copy

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

SGksIEknbSBkb2luZyBhIHNlcnZlciBhbmQgd2FudCB0byBhdm9pZCBtZW1vcnkgaW5uZWNlc2Fy
eSBvcGVyYXRpb25zLgpJIGhhdmUgYW4gYXJyYXkgb2YgaGVhZGVyczoKICBoZWFkZXJzX2FycmF5
CgpFYWNoIGhlYWRlciBpcyBhbiBvYmplY3Qgb2YgIkhlYWRlciIgY2xhc3M6CgoJY2xhc3MgSGVh
ZGVyCgkJYXR0cl9hY2Nlc3NvciA6bmFtZSwgOmJvZHkKCQlkZWYgaW5pdGlhbGl6ZShuYW1lLCBi
b2R5KQoJCQlAbmFtZSA9IG5hbWUKCQkJQGJvZHkgPSBib2R5CgkJZW5kCgllbmQKCgpUaGVyZSBh
cmUgYWxzbyBvdGhlcnMgc3BlY2lmaWMgaGVhZGVycyBzb29ucyBvZiAiSGVhZGVyIiBjbGFzczoK
CgljbGFzcyBGcm9tIDwgSGVhZGVyCgkJYXR0cl9hY2Nlc3NvciA6dXJpCgllbmQKCgpBdCB0aGUg
YmVnZ2luaW5nICJoZWFkZXJzX2FycmF5IiBqdXN0IGNvbnRhaW4gIkhlYWRlciIgb2JqZWN0cyBi
dXQKYWZ0ZXIgaW5zcGVjdGlvbiBJIHdhbnQgdG8gcmVwbGFjZSB0aGUgaGVhZGVyIHdpdGggQG5h
bWU9J0Zyb20nIHdpdGggYQoiRnJvbSIgb2JqZWN0IGJ1dCBzaW5jZSAibmFtZSIgYW5kICJib2R5
IiBhdHRyaWJ1dGVzIGFyZSB0aGUgc2FtZSBJCmRvbid0IHdhbnQgYSBtZW1vcnkgY29weSBvcGVy
YXRpb24gdG8gYWxsb2NhdGUgc3BhY2UgZm9yIG5ldyBvYmplY3QuCgpUaGlzIGlzOiBJIGp1c3Qg
d2FudCB0byBjaGFuZ2UgdGhlIENsYXNzIG9mIGEgIkhlYWRlciIgb2JqZWN0IHRvCiJGcm9tIiBj
bGFzcywga2VlcGluZyB0aGUgYXR0cmlidXRlcyB3aXRob3V0IG1lbW9yeSBjb3B5IG9wZXJhdGlv
biwgaXMKdGhlcmUgYW55IHdheT8gSSBpbWFnaW5lIGluIEMgSSdkIGRvIGl0IGJ5IHVzaW5nIHBv
aW50ZXJzLgoKClRoYW5rcyBmb3IgYW55IGhlbHAuCgoKCi0tIApJw7Fha2kgQmF6IENhc3RpbGxv
CjxpYmNAYWxpYXgubmV0Pgo=
 
J

Joel VanderWerf

Iñaki Baz Castillo said:
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
 
I

Iñaki Baz Castillo

MjAwOC80LzEyLCBKb2VsIFZhbmRlcldlcmYgPHZqb2VsQHBhdGguYmVya2VsZXkuZWR1PjoKCj4g
IFdoeSBkbyB5b3UgbmVlZCBhIEZyb20gY2xhc3MgdGhhdCBpcyBkaXN0aW5jdCBmcm9tIEhlYWRl
cj8KCkJlY2F1c2UgaW4gYW4gaW5pdGlhbCBwYXJzaW5nIEkganVzdCBnZXQgYSBoZWFkZXJzIGFy
cmF5LCB3aGlvdHUKaW5zcGVjdGluZyBlYWNoIG9mIHRoZW0uCkxhdGVyLCBpZiBJIG5lZWQsIEkg
bG9vayBmb3Igc29tZSBzcGVjaWZpYyBoZWFkZXJzIChGcm9tLCBUby4uLikgYW5kCm5lZWQgdG8g
YWRkIHNvbWUgbWV0aG9kcyB0byB0aGVtLgoKCj4gRGVwZW5kaW5nIG9uIHRoZQo+IHJlYXNvbiwg
aXQgbWlnaHQgd29yayB0byBtYWtlIEZyb20gYSBtb2R1bGU6Cj4KPiAgbW9kdWxlIEZyb20KPiAg
ICMgc3BlY2lhbCBGcm9tIG1ldGhvZHMgaGVyZQo+ICBlbmQKPgo+ICBoZWFkZXJzLmVhY2ggZG8g
fGh8Cj4gICBpZiBoLm5hbWUgPT0gIkZyb20iCj4gICAgIGguZXh0ZW5kIEZyb20KPiAgIGVuZAo+
ICAgIyBvciBtYXliZSBzb21ldGhpbmcgbGlrZToKPiAgICMgaC5leHRlbmQgY29uc3RfZ2V0KGgu
bmFtZSkKPiAgZW5kCgpUaGFua3MsIHRoaXMgaXMgZ3JlYXQhIEkgZGlkbid0IGtub3cgImV4dGVu
ZCIgbWV0aG9kLgoKCi0tIApJw7Fha2kgQmF6IENhc3RpbGxvCjxpYmNAYWxpYXgubmV0Pgo=
 
R

Robert Klemme

2008/4/12 said:
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.
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
 
I

Iñaki Baz Castillo

El Lunes, 14 de Abril de 2008, Robert Klemme escribi=F3:
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
 
G

Gary Wright

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=
 
I

Iñaki Baz Castillo

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
 
G

Gennady Bystritsky

I=F1aki Baz Castillo said:
El Lunes, 14 de Abril de 2008, Gary Wright escribi=F3:

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.
 
I

Iñaki Baz Castillo

MjAwOC80LzE1LCBHZW5uYWR5IEJ5c3RyaXRza3kgPEdlbm5hZHkuQnlzdHJpdHNreUBxdWVzdC5j
b20+Ogo+IE5vdCB0cnVlLiBUbyB2ZXJpZnkgaXQsIGFmdGVyIHlvdSBkbyAiZnJvbS5uYW1lID0g
aGVhZGVyLm5hbWUiLCB0cnkgdGhpczoKPgo+ICBwdXRzIGhlYWRlci5uYW1lLm9iamVjdF9pZAo+
ICBwdXRzIGZyb20ubmFtZS5vYmplY3RfaWQKPgo+ICBZb3Ugd2lsbCBzZWUgc2FtZSBvYmplY3Qg
aWQsIG1lYW5pbmcgdGhhdCB5b3UgaGF2ZSBhIHJlZmVyZW5jZSwgbm90IGEgbmV3IG9iamVjdC4K
Ck9oaCwgdGhhdCdzIGFubm95aW5nIGZvciBtZSEKWW91IGFyZSByaWdodCwgYm90aCBhcmUgdGhl
IHNhbWUgb2JqZWN0cyAqKnVudGlsKiogSSBtb2RpZnkgb25lIG9mIHRoZW0uIEkgbWVhbjoKCiAg
ZnJvbS5uYW1lID0gaGVhZGVyLm5hbWUKICA9PiAiQUFBQSIKICBmcm9tLm5hbWUuIG9iamVjdF9p
ZCA9PSBoZWFkZXIubmFtZS5vYmplY3RfaWQKICA9PiB0cnVlCgpTbyBpbiB0aGlzIG1vbWVudCBm
cm9tLm5hbWUuIG9iamVjdF9pZCA9PSBoZWFkZXIubmFtZS5vYmplY3RfaWQuIEJ1dAppZiBJIGNo
YW5nZSB0aGUgdmFsdWU6CgogIGZyb20ubmFtZSA9ICJCQkJCIgogIGZyb20ubmFtZS4gb2JqZWN0
X2lkID09IGhlYWRlci5uYW1lLm9iamVjdF9pZAogID0+IGZhbHNlCgpUaGVuIGZyb20ubmFtZS4g
b2JqZWN0X2lkICE9IGhlYWRlci5uYW1lLm9iamVjdF9pZCwgc28gdGhlbiB0aGVyZSBhcmUKdHdv
IHZhbHVlcyBpbiBtZW1vcnkgYXQgc2FtZSB0aW1lLgoKUmVnYXJkcy4KCgotLSAKScOxYWtpIEJh
eiBDYXN0aWxsbwo8aWJjQGFsaWF4Lm5ldD4K
 
J

Jesús Gabriel y Galán

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.
 
G

Gennady Bystritsky

I=F1aki Baz Castillo said:
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.
 
I

Iñaki Baz Castillo

MjAwOC80LzE1LCBHZW5uYWR5IEJ5c3RyaXRza3kgPEdlbm5hZHkuQnlzdHJpdHNreUBxdWVzdC5j
b20+OgoKPiBZb3UgZG8gbm90IGNoYW5nZSB0aGUgdmFsdWUsIHlvdSBqdXN0IGFzc2lnbiBhIHJl
ZmVyZW5jZSB0byBhIG5ldyBzdHJpbmcuIFRvIGNoYW5nZSB0aGUgY29udGVudCBvZiBhIHN0cmlu
ZyBvYmplY3QgeW91IG5lZWQgdG8gdXNlIHJlcGxhY2UoKSBvbiBpdC4gSXQgbG9va3MgbGlrZSBp
dCBvbWl0cyB5b3UgdGhhdCAiQUFBQSIgYW5kICJCQkJCIiBtYWtlIHN0cmluZyBvYmplY3RzIGFs
cmVhZHkgYW5kIG5vdCBqdXN0IHdoZW4geW91IGFzc2lnbiB0aGVtIHRvIGEgdmFyaWFibGUuCgpU
aGFua3MgdG8gYm90aCwgSSd2ZSB1bmRlcnN0b29kIG5vdzoKCmE9IkFBQUEiCj0+ICJBQUFBIgoK
YS5vYmplY3RfaWQKPT4gLTYwNjA1NjEzOAoKYT0iQkJCQiIKPT4gIkJCQkIiCgphLm9iamVjdF9p
ZAo9PiAtNjA2MDYzNDk4CgoKVGhhbmtzIDopCgoKLS0gCknDsWFraSBCYXogQ2FzdGlsbG8KPGli
Y0BhbGlheC5uZXQ+Cg==
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top