# A Question Of Coupling

**URL:** <https://www.ruby-forum.com/t/a-question-of-coupling/133704>\
**Category:** Ruby\
**Created:** [April 2, 2008, 8:47pm UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704 "2008-04-02T20:47:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [April 2, 2008, 8:47pm UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704/1 "2008-04-02T20:47:46Z")

</div>

I have a choice to make about a class interface. This is a very very  
simplified “foo” demo of that choice.

#1

class Foo  
def initialize(bar)  
@bar = bar  
end

```
def okay?
  bar.okay?
end

```

end

bar = Bar.new  
Foo.new(bar)

Or #2

class Foo  
def initialize( opts )  
@okay = opts[:okay]  
end

```
def okay?
  @okay
end

```

end

bar = Bar.new  
Foo.new(:okay =\> bar.okay?)

Now, my inner OOP Angel is telling me to take door #2 in order to  
avoid strong coupling between Bar and Foo. But, my Red Ruby Devil is  
saying “Duck typing, you fool. It doesn’t matter anymore!”

Is he right? Has Ruby completely changed the game? If so, why aren’t  
more Rubyists using OStruct-esque option passing?

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [April 2, 2008, 8:56pm UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704/2 "2008-04-02T20:56:47Z")

</div>

On Thu, 3 Apr 2008 03:46:49 +0900, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Now, my inner OOP Angel is telling me to take door #2 in order to  
> avoid strong coupling between Bar and Foo. But, my Red Ruby Devil is  
> saying “Duck typing, you fool. It doesn’t matter anymore!”
> 
> Is he right? Has Ruby completely changed the game?

I don’t see why that would be true in this case. In #1, Foo’s  
implementation depends on Bar’s public interface, whereas in #2,  
there is no coupling at all between them.

Put another way: duck typing is still, in a sense, typing. In #1,  
you aren’t constrained to pass in a Bar, specifically, but you must  
still pass in an object which satisfies the same un-named object  
protocol as instances of Bar do.

(Perhaps we should call it “ninja typing”?)

> If so, why aren’t more Rubyists using OStruct-esque option passing?

Ruby doesn’t make it as frictionless as it could be, particularly if  
you want default values for your options.

-mental

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [April 2, 2008, 9:00pm UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704/3 "2008-04-02T21:00:58Z")

</div>

That said, I’m not sure that the issue of coupling necessarily settles  
the question. The more actual behavior (rather than POD) embodied by  
Bar,  
the more #1 could potentially be desirable as an embodiment of the  
Strategy Pattern.

-mental

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [April 2, 2008, 9:18pm UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704/4 "2008-04-02T21:18:12Z")

</div>

My issue with #2 is that the return value of bar.okay? might change,  
but with this implementation Foo#okay? won’t ever change.

Jason

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [April 3, 2008, 12:28am UTC](https://www.ruby-forum.com/t/a-question-of-coupling/133704/5 "2008-04-03T00:28:51Z")

</div>

On Apr 2, 3:17 pm, “Jason R.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> My issue with #2 is that the return value of bar.okay? might change,  
> but with this implementation Foo#okay? won’t ever change.

That’s a good point. I guess that crystalizes the coupling.

Coupled:

class Foo  
def initialize(bar)  
@bar = bar  
end

Decoupled:

class Foo  
def initialize(bar)  
@bar = bar.dup  
end

T.
