From: Paul A. on
Hello,

I have a general question about OOP with Ruby. If I have 2 class: Home
and Person for instance, such as:

>> class Home
>> def initialize
>> @person1 = Person.new
>> @person2 = Person.new
>> # ...
>> end
>>
>> def open_a_window; end
>> # ...
>> end

>> class Person
>> def play_wii_game; end
>> end

Then, a home instance can include a lot of people. And that's cool. And
a home instance can apply action on a person using a method just like:
@person2.play_wii_game

But if a person want to open a window in its home? Here, with a such
design it's impossible, isn't it.

So to allow this kind of action, I think we need to pass as parameter
self inside Home initialization process, becoming:

>> class Home
>> def initialize
>> @person1 = Person.new(self)
>> @person2 = Person.new(self)
>> # ...
>> end
>>
>> def open_a_window; end
>> # ...
>> end

>> class Person
>> def initialize(home)
>> @home = home
>> end
>>
>> def open_a_window
>> @home.open_a_window
>> end
>>
>> def play_wii_game; end
>> end

Now, a instantiated person can do it using open_a_window proxy method.
And any other proxifyable home's methods.

But is it ethics? I mean, is that lawful under the principles of
object-oriented programming. Maybe this is so much power, to pass self
inside person instance inside its home... 'cause it's almost as if there
was no class, no partitioning.

What do you think about this?
Thanks for any considerations.
--
Posted via http://www.ruby-forum.com/.

From: Intransition on


On Jun 19, 9:56 am, "Paul A." <cyril.st...(a)gmail.com> wrote:
> Hello,
>
> I have a general question about OOP with Ruby.  If I have 2 class: Home
> and Person for instance, such as:
>
> >> class Home
> >>   def initialize
> >>     @person1 = Person.new
> >>     @person2 = Person.new
> >>     # ...
> >>   end
>
> >>   def open_a_window; end
> >>   # ...
> >> end
> >> class Person
> >>   def play_wii_game; end
> >> end
>
> Then, a home instance can include a lot of people. And that's cool.  And
> a home instance can apply action on a person using a method just like:
> @person2.play_wii_game
>
> But if a person want to open a window in its home?  Here, with a such
> design it's impossible, isn't it.
>
> So to allow this kind of action, I think we need to pass as parameter
> self inside Home initialization process, becoming:
>
>
>
> >> class Home
> >>   def initialize
> >>     @person1 = Person.new(self)
> >>     @person2 = Person.new(self)
> >>     # ...
> >>   end
>
> >>   def open_a_window; end
> >>   # ...
> >> end
> >> class Person
> >>   def initialize(home)
> >>     @home = home
> >>   end
>
> >>   def open_a_window
> >>     @home.open_a_window
> >>   end
>
> >>   def play_wii_game; end
> >> end
>
> Now, a instantiated person can do it using open_a_window proxy method.
> And any other proxifyable home's methods.
>
> But is it ethics? I mean, is that lawful under the principles of
> object-oriented programming. Maybe this is so much power, to pass self
> inside person instance inside its home... 'cause it's almost as if there
> was no class, no partitioning.
>
> What do you think about this?
> Thanks for any considerations.

It's fine. But why is Home creating people? Perhaps they should be
added to a home? In which case you could create a home and then a
person with a home and the person would be automatically added to that
home.

home = Home.new
person1 = Person.new(home1)

Or you could create both the home and person separately but when you
add the person to the home they will pick up a reference to it.

home = Home.new
person1 = Person.new
home << person1

In Home:

class Home

def <<(person)
@persons << person
person.home = self
end

~trans

From: Ammar Ali on
On Sat, Jun 19, 2010 at 4:56 PM, Paul A. <cyril.staff(a)gmail.com> wrote:
> But is it ethics? I mean, is that lawful under the principles of
> object-oriented programming. Maybe this is so much power, to pass self
> inside person instance inside its home... 'cause it's almost as if there
> was no class, no partitioning.

There is nothing wrong from an OOP point of view with one object
containing a reference to another object. Even in the real world, it
makes sense that a person knows where their home is.

In some languages, like C++, this can introduce some typing and API
complications, but not in Ruby where methods are invoked by sending
messages to the objects.

The problems that you might have with this approach are related to
design requirements. For example, what if one person can, optionally,
have more than one home?


Ammar

From: Michael Fellinger on
On Sun, Jun 20, 2010 at 12:37 AM, Ammar Ali <ammarabuali(a)gmail.com> wrote:
> On Sat, Jun 19, 2010 at 4:56 PM, Paul A. <cyril.staff(a)gmail.com> wrote:
>> But is it ethics? I mean, is that lawful under the principles of
>> object-oriented programming. Maybe this is so much power, to pass self
>> inside person instance inside its home... 'cause it's almost as if there
>> was no class, no partitioning.
>
> There is nothing wrong from an OOP point of view with one object
> containing a reference to another object. Even in the real world, it
> makes sense that a person knows where their home is.
>
> In some languages, like C++, this can introduce some typing and API
> complications, but not in Ruby where methods are invoked by sending
> messages to the objects.
>
> The problems that you might have with this approach are related to
> design requirements. For example, what if one person can, optionally,
> have more than one home?

I think I'd model it somewhat like this (untested):

class Window
attr_accessor :open
end

class Home
attr_accessor :window

def initialize
@window = Window.new
end
end

class Person
attr_accessor :location

def enter(location)
self.location = location
end

def open_window
if location.window.respond_to?(:open=)
location.window.open = true
else
raise("The location doesn't have any windows you can open")
end
end
end

guy = Person.new
home = Home.new
guy.enter(home)
guy.open_window

--
Michael Fellinger
CTO, The Rubyists, LLC

From: Josh Cheek on
[Note: parts of this message were removed to make it a legal post.]

On Sat, Jun 19, 2010 at 8:56 AM, Paul A. <cyril.staff(a)gmail.com> wrote:

> Hello,
>
> I have a general question about OOP with Ruby. If I have 2 class: Home
> and Person for instance, such as:
>
> >> class Home
> >> def initialize
> >> @person1 = Person.new
> >> @person2 = Person.new
> >> # ...
> >> end
> >>
> >> def open_a_window; end
> >> # ...
> >> end
>
> >> class Person
> >> def play_wii_game; end
> >> end
>
> Then, a home instance can include a lot of people. And that's cool. And
> a home instance can apply action on a person using a method just like:
> @person2.play_wii_game
>
> But if a person want to open a window in its home? Here, with a such
> design it's impossible, isn't it.
>
> So to allow this kind of action, I think we need to pass as parameter
> self inside Home initialization process, becoming:
>
> >> class Home
> >> def initialize
> >> @person1 = Person.new(self)
> >> @person2 = Person.new(self)
> >> # ...
> >> end
> >>
> >> def open_a_window; end
> >> # ...
> >> end
>
> >> class Person
> >> def initialize(home)
> >> @home = home
> >> end
> >>
> >> def open_a_window
> >> @home.open_a_window
> >> end
> >>
> >> def play_wii_game; end
> >> end
>
> Now, a instantiated person can do it using open_a_window proxy method.
> And any other proxifyable home's methods.
>
> But is it ethics? I mean, is that lawful under the principles of
> object-oriented programming. Maybe this is so much power, to pass self
> inside person instance inside its home... 'cause it's almost as if there
> was no class, no partitioning.
>
> What do you think about this?
> Thanks for any considerations.
> --
> Posted via http://www.ruby-forum.com/.
>
>
Plus, you get a nice little benefit in that the Person#open_a_window method
can contain the conditionals for dealing with the edge case of when there is
no home.

class Person
def open_a_window
@home.open_a_window if @home
end
def has_home?
!!@home
end
end

Then later you can say things like
person.open_a_window if person.hot?

rather than having to cart the exception logic all over your implementaion
person.open_a_window if person.hot? && person.has_home?

Though, I suppose, it is a rather limited model in that your person may be
at work, or at a friend's home.