b = B.new
b.a = "some data"
b.b = "some more data"
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
Offhand it’s possible that you’re thinking in a
C++ fashion and should simply do it another way.
You could add a class method for B that would
create an instance of A and return it…
class B
def B.to_A
x = A.new
x.a = self.a
x
end
end
That’s consistent with the ordinary principles of
an object knowing how to convert itself and a child
class having knowledge of a parent but not vice versa.
Hal
···
----- Original Message -----
From: “Michael Garriss” mgarriss@earthlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, July 31, 2003 4:53 PM
Subject: Extracting a parent class
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
Why:
b.class == B
b.class.superclass == A
b.class.superclass.new == A.new
Cheers,
Daniel.
···
On Fri, Aug 01, 2003 at 06:53:01AM +0900, Michael Garriss wrote:
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
Weekly Smile * * * * * * * * * * * * * * * * * * * * * * * *
Sign in a hotel in Athens:
Visitors are expected to complain at the office between the hours
of 9 and 11 A.M. daily.
Sorry…I should have been more clear. While this works it does not
mantain the state. I would like all the members of ‘b’ that are class
A members to be set in ‘a’.
Daniel Carrera wrote:
···
Answer:
a = b.class.superclass.new
Why:
b.class == B
b.class.superclass == A
b.class.superclass.new == A.new
Cheers,
Daniel.
On Fri, Aug 01, 2003 at 06:53:01AM +0900, Michael Garriss wrote:
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
It is VERY possible that I should be doing it in another way. My
motivation: I have a client/server arch. The server maintains objects
and a database. When the client needs something I do not want the
client to have full access to all the info found in those server side
objects. Some of it would be bad for the client to know. I have
classes the client side can use and I add the additional things the
server knows about the object by creating a subclass of the client class
and then just adding the one or two ‘secret’ members. Does this make sense?
Hal E. Fulton wrote:
···
----- Original Message -----
From: “Michael Garriss” mgarriss@earthlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, July 31, 2003 4:53 PM
Subject: Extracting a parent class
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
I don’t know of a simple, direct way to do this.
Offhand it’s possible that you’re thinking in a
C++ fashion and should simply do it another way.
You could add a class method for B that would
create an instance of A and return it…
class B
def B.to_A
x = A.new
x.a = self.a
x
end
end
That’s consistent with the ordinary principles of
an object knowing how to convert itself and a child
class having knowledge of a parent but not vice versa.
Oh, sorry.
In that case I don’t imagine it’s possible by default because in general
there might not be an “obvious” way to turn class B into class A.
You should make a B#to_A method.
Cheers,
Daniel.
···
On Fri, Aug 01, 2003 at 07:09:07AM +0900, Michael Garriss wrote:
Sorry…I should have been more clear. While this works it does not
mantain the state. I would like all the members of ‘b’ that are class
A members to be set in ‘a’.
Daniel Carrera wrote:
Answer:
a = b.class.superclass.new
Why:
b.class == B
b.class.superclass == A
b.class.superclass.new == A.new
Cheers,
Daniel.
On Fri, Aug 01, 2003 at 06:53:01AM +0900, Michael Garriss wrote:
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
Weekly Smile * * * * * * * * * * * * * * * * * * * * * * * *
Sign in a hotel in Athens:
Visitors are expected to complain at the office between the hours
of 9 and 11 A.M. daily.
It is VERY possible that I should be doing it in another way. My
motivation: I have a client/server arch. The server maintains objects
and a database. When the client needs something I do not want the
client to have full access to all the info found in those server side
objects. Some of it would be bad for the client to know. I have
classes the client side can use and I add the additional things the
server knows about the object by creating a subclass of the client class
and then just adding the one or two ‘secret’ members. Does this make sense?
It is VERY possible that I should be doing it in another way. My
motivation: I have a client/server arch. The server maintains objects
and a database. When the client needs something I do not want the
client to have full access to all the info found in those server side
objects. Some of it would be bad for the client to know. I have
classes the client side can use and I add the additional things the
server knows about the object by creating a subclass of the client class
and then just adding the one or two ‘secret’ members. Does this make sense?
Perhaps containment would be a better solution than inheritance?
class ClientThingy
attr :foo, :bar, :baz
end
class ServerThingy
attr :client_thingy
def initialize @client_thingy = ClientThingy.new
end
end
Also, have you looked at DRb? It will allow you to have a clean
division between server-side and client-side.
I suppose that containment is a good idea but I do have methods that
expect objs of the client side base class. I could rewrite them to add
the check the class of the incoming obj. I think that I will just
continue to use to_SomeClass type methods. It’s just a pain to have to
keep them upto date.
It is VERY possible that I should be doing it in another way. My
motivation: I have a client/server arch. The server maintains objects
and a database. When the client needs something I do not want the
client to have full access to all the info found in those server side
objects. Some of it would be bad for the client to know. I have
classes the client side can use and I add the additional things the
server knows about the object by creating a subclass of the client class
and then just adding the one or two ‘secret’ members. Does this make sense?
Perhaps containment would be a better solution than inheritance?
class ClientThingy
attr :foo, :bar, :baz
end
class ServerThingy
attr :client_thingy
def initialize @client_thingy = ClientThingy.new
end
end
Also, have you looked at DRb? It will allow you to have a clean
division between server-side and client-side.
Just in case anyone is following this, I have a new solution to my
problem. It only works if each instance variable in the parent class is
accessable. Anyone who can solve this or has a hint…plz tell me!
Here’s the test code:
module SuperCastable
def to_super
super_obj = self.class.superclass.new
instance_variables.each { |var|
begin
eval “super_obj.#{var[1…-1]} = #{var}”
rescue NoMethodError
end
}
super_obj
end
end
class A
attr_accessor :a
end
class B < A
include SuperCastable
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.to_super
Daniel Carrera wrote:
···
Oh, sorry.
In that case I don’t imagine it’s possible by default because in general
there might not be an “obvious” way to turn class B into class A.
You should make a B#to_A method.
Cheers,
Daniel.
On Fri, Aug 01, 2003 at 07:09:07AM +0900, Michael Garriss wrote:
Sorry…I should have been more clear. While this works it does not
mantain the state. I would like all the members of ‘b’ that are class
A members to be set in ‘a’.
Daniel Carrera wrote:
Answer:
a = b.class.superclass.new
Why:
b.class == B
b.class.superclass == A
b.class.superclass.new == A.new
Cheers,
Daniel.
On Fri, Aug 01, 2003 at 06:53:01AM +0900, Michael Garriss wrote:
Sorry about the newbie question but…
class A
attr_accessor :a
end
class B < A
attr_accessor :b
end
b = B.new
b.a = “some data”
b.b = “some more data”
a = b.???
How do I set ‘a’ from ‘b’ so that a is of class A and not class B? I
don’t want the extra info, I want just the subset of members found in
the parent class. Is there a way to cast?
Unless you were to use the Struct class instead of a normal class, in
which case you can tell what should stay and what should go.
e.g.
class Struct
def cast_as(klass)
raise “Not a Class” unless klass.kind_of?(Class)
raise “Not a Struct” unless klass.ancestors.include?(Struct)
obj = klass.new()
members.each do |name|
obj[name] = self[name] if obj.members.include?(name)
end
obj
end
end
StructA = Struct.new(‘StructA’,:alpha, :beta)
StructB = Struct.new(‘StructB’,:alpha, :beta, :gamma)
foo = Struct::StructB.new(1,2,3)
bar = foo.cast_as(Struct::StructA)
p foo,bar
With a bit more effort you could try a reverse castable object - ie.
one which would preserve members unused by the target class and copy all
instance variables, but I don’t think that that is what is required
here.
HTH,
Geoff
···
On Fri, Aug 01, 2003 at 07:12:19AM +0900, Daniel Carrera wrote:
Oh, sorry. In that case I don’t imagine it’s possible by default
because in general there might not be an “obvious” way to turn class B
into class A.
Or query based on interface – ask if it has the methods you expect, not
the inheritance.
···
On Thu, 2003-07-31 at 16:53, Michael Garriss wrote:
I suppose that containment is a good idea but I do have methods that
expect objs of the client side base class. I could rewrite them to add
the check the class of the incoming obj. I think that I will just
continue to use to_SomeClass type methods. It’s just a pain to have to
keep them upto date.
Just in case anyone is following this, I have a new solution to my
problem. It only works if each instance variable in the parent class is
accessable. Anyone who can solve this or has a hint…plz tell me!
Just in case anyone is following this, I have a new solution to my
problem. It only works if each instance variable in the parent class is
accessable. Anyone who can solve this or has a hint…plz tell me!
You can get at anything you want using #instance_eval.