Hello everyone,

I'm quite new to Ruby, with a strong background in PHP.

I had a great time finding my way around in Ruby, because it is a =
fantastic language. However, right now I'm a bit stuck regarding the =
issue of loose coupling / inversion of control / writing testable units.

I spent the last days reading a lot of articles, but feel sort of =
puzzled now.

As far as I can see, there are several approaches. I will start with my =
own, which probably is the weirdest of all - feel free to dissect it.

Let's say I have 2 classes, SomeClass and OtherClass, and SomeClass =
depends on OtherClass, because in some cases it needs to create an =
instance of this class, and in others it doesn't, which is why we can't =
simply pass an already created instance of OtherClass into SomeClass.

This is how it could be done using no DI at all:

class SomeClass
  def do_something(a, b)
    c =3D a + b
    if (c > 5) then
      o =3D OtherClass.new()
      o.log(c)
    end
  end
end

s =3D SomeClass.new
s.do_something(1, 2)

Which of course doesn't allow me to replace "o" with a mock object for =
testing etc.


This is how it might be done using the fact that ruby classes are =
objects (my approach):

class SomeClass
  def do_something(a, b, logObjectClass)
    c =3D a + b
    if (c > 5) then
      o =3D logObjectClass.new()
      o.log(c)
    end
  end
end

s =3D SomeClass.new
s.do_something(1, 2, OtherClass)

This way, I can inject into SomeClass which class to actually use - as =
long as whatever I pass using logObjectClass supports the expected =
protocol, all should be fine. I could easily inject a mock log object =
for my tests.

But, I couldn't find any articles recommending this approach, and I =
guess there's a reason for that...


Another solution which seems to be more along "the Ruby way" is this:

class SomeClass
  def do_something(a, b)
    c =3D a + b
    if (c > 5) then
      o =3D get_logger()
      o.log(c)
    end
  end

  def get_logger()
    OtherClass.new()
  end
end

// Replacing with mock object:
s =3D SomeClass.new
def s.get_logger()
  MockLoggerClass.new()
end
s.do_something(1, 2)

Could someone help me to understand which approach is better, and why? =
Or if maybe I'm getting it completely wrong?

Thanks in advance,

--=20
 Manuel