How do I make lots of classes aware of each other?

I’m apparently missing something fundamental in my knowledge of classes
and how they interoperate.

Let’s say I have lots of classes, such as the following:

class Foo
def method
puts “hi”
end
end

class Bar
def method
puts “hi”
end
end

And I want to write another class that uses all of those classes. For
example:

class Baz
foo.method
bar.method
end

What I’m doing right now is initiating all the classes as follows:

$foo = Foo.new
$bar = Bar.new

So I then have:

class Baz
$foo.method
$bar.method
end

But this has to be wrong (?)

I could make them all modules and then include them as needed, but I’d
still end up with:

class baz
include Foo
include Bar
…x20ish

Essentially, I have about 20 classes and many of them talk to each
other, so they have to be aware of each other. What’s the right way to
structure all of this?

Many thanks in advance!

Andrew

You can use send which as you would expect sends messages to an object.
You
can build wrapper methods around that as it’s a oops primative. The
design
pattern you may want to look at (which is just an array of instances)
would
be to create an observer class which enumerates through the array
depending
on your use case conditions will send the appropriate message to the
objects within the array.

And no you want to avoid using the global variables. There are sort of
scoped class variables with the double at @@foo which remove the need to
create the observer class but it’s probably better to avoid those as
well.

~Stu

Thanks.

I was hoping for an easy answer and it sounds like there isn’t one.

It does make me just want to remove classes altogether and just make
sure the method names are all unique within one giant namespace… I
know that’s even worse than using the globals, but it sure would be a
heck of a lot easier overall.

On 07/01/2013 09:38 PM, Andrew S. wrote:

Thanks.

I was hoping for an easy answer and it sounds like there isn’t one.

It does make me just want to remove classes altogether and just make
sure the method names are all unique within one giant namespace… I
know that’s even worse than using the globals, but it sure would be a
heck of a lot easier overall.

Why do you have so many apparently rather tightly coupled classes? Maybe
the solution is to rethink your overall design to create fewer,
more generalized classes.

If you could provide a little more detailed example regarding 3 or 4 of
the classes demonstrating how they relate to each other, someone may be
able to lead you in a better direction.

-Jeremy

On Mon, Jul 1, 2013 at 7:14 PM, Andrew S. [email protected] wrote:

foo.method
class Baz
include Foo


Posted via http://www.ruby-forum.com/.

Initialize Baz with the foo and the bar:

class Foo
def method
puts “hi from Foo”
end
end

class Bar
def method
puts “hi from Bar”
end
end

class Baz
def initialize(methodables)
@methodables = methodables
end

def call
@methodables.each { |methodable| methodable.method }
end
end

baz = Baz.new [Foo.new, Bar.new]
baz.call

>> hi from Foo

>> hi from Bar

Andrew look at Josh’s example. That’s an observer. A great example. The
Baz
Observer pattern =)

Also consider this. Baz becomes sort of like main … but just for
object’s
it’s aware of. If you had another set like classes for a Lorem class and
Ipsom class which instances are owned by a Dolor Observer object you
could
create another level observer which owns both Baz and Dolor.

Of course there are more than one way to skin a cat. Considering top
level
of your application where self is actually main you can simply remove
scope
and program it like a shell script where everything is accessible from
your
normal top down execution. Your dots act like pipes because ruby allows
data types to be first class which makes object.method or object.send(
:method, :&message)

%w{LOrem IPsum DOlr}.send( :map, &:swapcase)
=> [“loREM”, “ipSUM”, “doLR”]

Of course send doesn’t have to be used. You could just do:
%w{LOrem IPsum DOlr}.map( &:swapcase)
or with a multi-line

[“loREM”, “ipSUM”, “doLR”].map do |baz|
baz.swapcase
end

and one liner
[“loREM”, “ipSUM”, “doLR”].map {|baz| baz.swapcase}

Though I’m using string objects in an array it would be no different
than
your custom classes communicating within their own functionality and
definition.

Using foo-bar-baz for learning this probably isn’t the best approach. It
may be better to talk about what your modeling and what your program
will
be doing. It will get you further if your going for a proper abstraction
which subsequently is something this programming language proves to
impose
no limitations on whether your implementing on the classical class
templates and returned results by falling through ancestor inheritance
which is an abstraction itself of the message passing paradigm from
smalltalk or doing it like a procedural macro shell script or stack
based C
program or functional lispy meta programming yielding values forward
recursively. Ruby will allow you to do this any way you please. It’s up
to
you to find which style you prefer and of course solve your domain
problem
in the process.

Good luck and enjoy hacking Ruby

~Stu

Jeremy B. wrote in post #1114156:

Why do you have so many apparently rather tightly coupled classes? Maybe
the solution is to rethink your overall design to create fewer,
more generalized classes.

This is a fair comment. I think I need to step back and look at my
design as a next step.

Cheers,

Andrew

On Tue, Jul 2, 2013 at 2:14 AM, Andrew S. [email protected] wrote:

I’m apparently missing something fundamental in my knowledge of classes
and how they interoperate.

Essentially, I have about 20 classes and many of them talk to each
other, so they have to be aware of each other. What’s the right way to
structure all of this?

You have received excellent replies already. I’d just like to point out
one detail: you do not necessarily want to make classes aware of each
other
but rather instances. Indirectly this, of course, makes classes aware
of
each other via the knowledge of methods to be called that each has.

One way to achieve what you want may be to have a method somewhere which
configures a set of objects knowing each other and returns an instance
used
as an entry point.

But we’re hugely speculating here as long as we do not see the real
purposes of those classes. Without that it’s impossible to suggest a
proper pattern. This cannot be done with Foo and Bar.

Kind regards

robert

Am 02.07.2013 02:14, schrieb Andrew S.:

Essentially, I have about 20 classes and many of them talk to each
other, so they have to be aware of each other. What’s the right way to
structure all of this?

Many thanks in advance!

Andrew

I think your question and example is just too general to give
meaningful advice. There are countless ways to have classes or
objects interact with each other.

The point is: what are you trying to model, what do your
classes represent?

Regards,
Marcus

Perhaps an example would help. I struggled for a while with the links
between classes in an Excel-style structure that I made.

Here’s the documentation:
http://rubydoc.info/gems/rubyexcel/0.2.7/index

This is the structure I used:

All classes are namespaced under “module RubyExcel”

“class Workbook” holds multiple instances of “class Sheet” in an
instance variable called @sheets. Method “Workbook#sheets” allows you to
loop through each sheet or select specific ones with an argument.

Each instance of “class Sheet” holds a reference to its “parent”
Workbook, and its data, held in “class Data”.

Each instance of classes Row, Column, Range, and Cell hold references to
their “parent” Sheet, which in turn provides a path to the Data and the
Workbook.
Because these classes exist merely to access specific sections of the
Sheet/Data, they can be garbage collected once they’re finished with,
and don’t need persistent tracking since all they do is reference
sections of the Data. They can be recreated when required.

When I say “parent”, I’m not talking about class inheritance, merely an
instance variable which holds a reference to an instance of another
class which is associated with the instance of the current class.

Here’s a simple example of the structure (without all the long object
ids in the output):

class Parent
attr_accessor :children
def initialize
@children = []
end
end

class Child
attr_accessor :parent
def initialize( parent )
@parent = parent
parent.children << self
end
end

parent = Parent.new
child1 = Child.new parent
child2 = Child.new parent

parent.children
=> child1, child2

child1.parent
=> parent

child2.parent
=> parent