Class in a Class problem

D

denize.paul

My intent is to create a class that has access to call a method in an
instantiation of another class

However my knowledge of Ruby classes (Ok classes in general) is
somewhat lacking

The example below is a LOT simplified But I need class B to call a
method within an instantiation of class A's.

one alternative is to seperate the classes and then just do "b=B.new
(a)" but I think that looks really messy and
- I have then to check a bunch of stuff about the parameter a
- I would have a world of more hurt trying to ensure that only one B
instantiation pointed to each a

Can anyone help? Or tell me that I am doing this all wrong.


Paul

-----

class A
class B
def initialize()
puts "b init"
print_stuff()
end
end

def B
return B
end

def print_stuff()
puts "here"
end
end

a = A.new()
b = a.B.new()
 
P

Phlip

- I have then to check a bunch of stuff about the parameter a
- I would have a world of more hurt trying to ensure that only one B
instantiation pointed to each a
class A
class B
def initialize()
puts "b init"
print_stuff()
end
end

def B
return B
end

def B(*args)
@b ||= B.new(self, *args)
end
def print_stuff()
puts "here"
end
end

a = A.new()
b = a.B(my_args)
 
M

Michael Malone

om>
X-Received-From: This message has been automatically forwarded from the ruby-talk mailing list by a gateway at comp.lang.ruby. If it is SPAM, it did not originate at comp.lang.ruby. Please report the original sender, and not us. Thanks! For more details about this gateway, please visit: http://blog.grayproductions.net/categories/the_gateway
X-Mail-Count: 332790
X-Ml-Name: ruby-talk
X-Rubymirror: Yes
X-Ruby-Talk: <[email protected]>
Bytes: 4208
Xref: number1.nntp.dca.giganews.com comp.lang.ruby:327494

My intent is to create a class that has access to call a method in an
instantiation of another class

Here be dragons. Have you considered the inheritance idea? If a class
*needs* access to another class's private variables, then the
functionality either belongs in the same class or a child class. Whilst
this is technically legal, it really doesn't bode well. If you
absolutely need Class A to have exactly one instantiation of Class B you
might want to consider the Singleton design pattern for class B. Which
in ruby is _really_ difficult to implement...

include singleton #(or something along those lines) :)

and for B to be a class variable of A (@@b = B.new) which, if they act
like Java statics (and I think they do) the class variable has one
instantiation able to be accessed from any object of the class.

e.g
class B
def initialize()
end

def to_s
"This is class #{class}"
end
end

class A

@@b = B.new()

def intitialize()
puts @@b
end

end

But in truth, you will have to be a little less generic to get a better
answer. If you can give more details of what you're trying to achieve,
then please do, and I'll try and give better help.

Michael
However my knowledge of Ruby classes (Ok classes in general) is
somewhat lacking

The example below is a LOT simplified But I need class B to call a
method within an instantiation of class A's.

one alternative is to seperate the classes and then just do "b=B.new
(a)" but I think that looks really messy and
- I have then to check a bunch of stuff about the parameter a
- I would have a world of more hurt trying to ensure that only one B
instantiation pointed to each a

Can anyone help? Or tell me that I am doing this all wrong.


Paul

-----

class A
class B
def initialize()
puts "b init"
print_stuff()
end
end

def B
return B
end

def print_stuff()
puts "here"
end
end

a = A.new()
b = a.B.new()


=======================================================================
This email, including any attachments, is only for the intended
addressee. It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.
=======================================================================
 
M

matt neuburg

My intent is to create a class that has access to call a method in an
instantiation of another class

However my knowledge of Ruby classes (Ok classes in general) is
somewhat lacking

The example below is a LOT simplified But I need class B to call a
method within an instantiation of class A's.

one alternative is to seperate the classes and then just do "b=B.new
(a)" but I think that looks really messy and
- I have then to check a bunch of stuff about the parameter a
- I would have a world of more hurt trying to ensure that only one B
instantiation pointed to each a

Can anyone help? Or tell me that I am doing this all wrong.


Paul

-----

class A
class B
def initialize()
puts "b init"
print_stuff()
end
end

def B
return B
end

def print_stuff()
puts "here"
end
end

a = A.new()
b = a.B.new()

Maybe I'm reading your question wrong, but the concept "has access to
call" is misleading, it seems to me, since there is never lack of access
in Ruby. So what you're really asking, I'm guessing, is that when a B
instance is produced by an A instance, it should point to that A
instance. We can do that without even giving the B class a name:

class A
def b
Class.new do
def initialize(a)
@a = a
end
attr :a
end.new(self)
end
# other stuff that an A knows how to do
end

So now you say:

a = A.new
b = a.b
puts (b.a == a) #=> true

So we see that b's a is indeed pointing at the correct instance. So now
you can say

b.a.print_stuff

or anything else you like. Is that the spirit of what you're after?

m.
 
R

Robert Klemme

Maybe I'm reading your question wrong, but the concept "has access to
call" is misleading, it seems to me, since there is never lack of access
in Ruby. So what you're really asking, I'm guessing, is that when a B
instance is produced by an A instance, it should point to that A
instance. We can do that without even giving the B class a name:

class A
def b
Class.new do
def initialize(a)
@a = a
end
attr :a
end.new(self)
end
# other stuff that an A knows how to do
end

You are creating new classes all the time. I don't think this is a good
idea.

I am not sure what the OP really wants, if I'm not mistaken he wants to
prevent creation of B instances outside of A and also make sure there is
a 1:1 relationship between an A and a B instance.

First of all, the question is: why are they separated? We can't answer
that one from those abstract classes presented.

Hiding of class B for the outside could be done like this:

class A
@b = Class.new do
def print_stuff
puts "hoho"
end
end

def initialize
@b = self.class.instance_variable_get("@b").new
@b.print_stuff
end
end

a = A.new
p a

But a) this is not really hidden and b) this looks quite ugly.

Paul, what are you trying to accomplish?

Kind regards

robert
 
M

matt neuburg

Robert Klemme said:
You are creating new classes all the time. I don't think this is a good
idea.

I'm not sure what you mean about new *classes*. It is certainly true
that I didn't do anything prevent the user from calling "b" twice on the
same A instance, thus getting two different objects pointing at that
instance:

a = A.new
b = a.b # b is an instance whose "@a" points at "a"
bb = a.b # bb is a different instance whose "@a" points at "a"

But that's easy to solve if desired. Obviously the real problem here is
that I couldn't fathom what the OP was actually trying to *do*. m.
 
R

Robert Klemme

I'm not sure what you mean about new *classes*.

There is a Class.new in your definition of method b which means, every
time the method is invoked a new anonymous class is created - regardless
whether b is invoked several times on one or multiple instances.
It is certainly true
that I didn't do anything prevent the user from calling "b" twice on the
same A instance, thus getting two different objects pointing at that
instance:

a = A.new
b = a.b # b is an instance whose "@a" points at "a"
bb = a.b # bb is a different instance whose "@a" points at "a"

But that's easy to solve if desired. Obviously the real problem here is
that I couldn't fathom what the OP was actually trying to *do*. m.

I had similar difficulties. That's why I asked.

Kind regards

robert
 
I

Igor Pirnovar

+----------------------------------------------------+
| class A |
| def initialize; puts "class A"; end |
| class B |
| def initialize; puts "class B"; end |
| def test_b; puts "instance method in B"; end |
| end |
| def make_b; B.new; end |
| end |
| |
| a = A.new |
| b = a.make_b |
| b.test_b |
+----------------------------------------------------+

OUTPUT:
class A
class B
instance method in B
 

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

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top