From: Michał Zając on
Hello,
I write in ruby for few weeks and I have noticed that in ruby I use
class (static) methods more often than in "traditional" languages like
java or c#. In java I use instance methods for two purposes -
maintaining object state and to use polymorphic behaviour. In ruby
polymorphism is available to class methods as well as for instance ones
so I don't see need for using instance methods in stateless classes (for
example typical application / domain services).

It is common for ruby programmers or maybe I have miss something?

Best Regards,
Michał
From: Rein Henrichs on
On 2010-06-13 10:27:48 -0700, Michał Zając said:

> Hello,
> I write in ruby for few weeks and I have noticed that in ruby I use
> class (static) methods more often than in "traditional" languages like
> java or c#. In java I use instance methods for two purposes -
> maintaining object state and to use polymorphic behaviour. In ruby
> polymorphism is available to class methods as well as for instance ones
> so I don't see need for using instance methods in stateless classes
> (for example typical application / domain services).
>
> It is common for ruby programmers or maybe I have miss something?
>
> Best Regards,
> Michał

Classes are designed to instantiate objects. If you have classes that
consist solely of class methods then they aren't functioning as classes
at all but rather as convenient globally-available namespaces for
singleton methods, which is a very procedural style of progrmaming.
Procedural programming is not necessarily bad, but you are missing out
on a great deal of the power and flexibility of an OOP langauge by
writing procedural code.

Then again, if the system works for you and maintainability and other
core values do not appear to suffer, who's to say you're doing it
wrong? Even asking the question shows that you're thinking critically
about the tradeoffs involved here, which is a good start.

--
Rein Henrichs
http://puppetlabs.com
http://reinh.com

From: Robert Klemme on
2010/6/14 Rein Henrichs <reinh(a)reinh.com>:
> On 2010-06-13 10:27:48 -0700, Michał Zając said:
>
>> I write in ruby for few weeks and I have noticed that in ruby I use class
>> (static) methods more often than in "traditional" languages like java or c#.
>> In java I use instance methods for two purposes - maintaining object state
>> and to use polymorphic behaviour. In ruby polymorphism is available to class
>> methods as well as for instance ones so I don't see need for using instance
>> methods in stateless classes (for example typical application / domain
>> services).
>>
>> It is common for ruby programmers or maybe I have miss something?
>
> Classes are designed to instantiate objects. If you have classes that
> consist solely of class methods then they aren't functioning as classes at
> all but rather as convenient globally-available namespaces for singleton
> methods, which is a very procedural style of progrmaming. Procedural
> programming is not necessarily bad, but you are missing out on a great deal
> of the power and flexibility of an OOP langauge by writing procedural code.

As a compromise Michael could use module Singleton and thus define
instance methods without the overhead of creating new instances all
the time.

irb(main):001:0> require 'singleton'
=> true
irb(main):002:0> class Foo;end
=> nil
irb(main):003:0> (1..3).map { Foo.new }
=> [#<Foo:0x1029b494>, #<Foo:0x1029b478>, #<Foo:0x1029b45c>]
irb(main):004:0> class Foo; include Singleton; end
=> Foo
irb(main):005:0> (1..3).map { Foo.new }
NoMethodError: private method `new' called for Foo:Class
from (irb):5:in `block in irb_binding'
from (irb):5:in `each'
from (irb):5:in `map'
from (irb):5
from /opt/bin/irb19:12:in `<main>'
irb(main):006:0> (1..3).map { Foo.instance }
=> [#<Foo:0x10268b88>, #<Foo:0x10268b88>, #<Foo:0x10268b88>]
irb(main):007:0>

Singleton pattern allows for easier migration if at a later point in
time instances need state.

> Then again, if the system works for you and maintainability and other core
> values do not appear to suffer, who's to say you're doing it wrong? Even
> asking the question shows that you're thinking critically about the
> tradeoffs involved here, which is a good start.

Absolutely agree!

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

From: Michał Zając on
W dniu 2010-06-14 15:33, Robert Klemme pisze:
>
> As a compromise Michael could use module Singleton and thus define
> instance methods without the overhead of creating new instances all
> the time.
>

I think this is interesting idea.
I have spent much time in Java / C# environments with heavy use of
dependency injection pattern so maybe this is source of my aversion to
stateless classes manual instantiation - usually something else has done
it for me :D Using Singleton pattern is more similar to Service Locator
but it may be good alternative.

Thanks

From: Rein Henrichs on
On 2010-06-14 10:35:10 -0700, Michał Zając said:

> W dniu 2010-06-14 15:33, Robert Klemme pisze:
>>
>> As a compromise Michael could use module Singleton and thus define
>> instance methods without the overhead of creating new instances all
>> the time.
>>
>
> I think this is interesting idea.
> I have spent much time in Java / C# environments with heavy use of
> dependency injection pattern so maybe this is source of my aversion to
> stateless classes manual instantiation - usually something else has
> done it for me :D Using Singleton pattern is more similar to Service
> Locator but it may be good alternative.
>
> Thanks

Ruby's design patterns (in the Gang of Four sense) are extremely
lightweight compared to their Java equivalents. Rick Olsen's Design
Patterns in Ruby book shows good idiomatic Ruby implementations of the
GoF patterns. That said, I don't think you want a Pattern at all. I
think you want a more *object oriented* architecture.

IRT Singleton: I think that Singleton is just a way to cheat and get
global state that looks like instances. I didn't present it as a
solution because (imo) it's really just a restatement of the problem. I
try to avoid it for the same reasons that I try to avoid the classes
you're asking about. Let me put it this way: replace all of your
pseudo-classes (these classes that don't instantiate and are used as
singleton method holders) with this:

YourClass = Object.new

def YourClass.some_method
... do stuff ...
end

.... more ...

This is functionally equivalent. Does this look like good Ruby code? Is
this good OO design? If not, why not? The classes you're asking about
aren't (functionally) classes at all: they're just objects like this
one. You should object to them for the same reasons that you (may)
object to the above.

Also, Ruby has far better mechanisms than dependency injection. So much
so, in fact, that Rails core member and creator of two different Ruby
dep. injection libraries, Jamis Buck, recently gave a great talk about
why you don't need dependency injection in Ruby. Summary is here, and
is a good read if you're coming from heavy, "enterprisey" languages
like Java:
http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming.

Coming from a Java background, the best thing you can do is let go of
the heavy pattern-driven architectures that are common in
enterprise-land (the ServiceLocator, CachedTemplateFactoryProxyFactory,
whatever) and enjoy the freedom of working with simple, lightweight
classes and objects.

--
Rein Henrichs
http://puppetlabs.com
http://reinh.com