[rspec-users] class << self considered harmful... really?
brian.takita at gmail.com
Thu Nov 27 19:40:08 EST 2008
On Thu, Nov 27, 2008 at 6:43 PM, Mark Wilden <mark at mwilden.com> wrote:
> On Thu, Nov 27, 2008 at 1:59 PM, Brian Takita <brian.takita at gmail.com>
>> Its funny because I consider def self.foo harmful for a few reasons.
>> def self.method_name is often mixed with instance methods. This makes
>> reading the code confusing because there are two contexts that you
>> need to deal with.
> Solution: Don't do that.
When maintaining code, I often wish I could travel back in time and
tell the writer "Don't do that". :)
>> Also, like you mentioned, using def self. obfuscates an object
>> extraction that needs to happen. With class << self, I can think about
>> refactoring an object, rather than refactoring class methods. class <<
>> self allows me to think of class/modules in a more object oriented
> In general, in OOP, I've found class methods to be far less numerous than
> instance methods. Class methods by their very nature are not OOP - they're
> not much different than global functions. In Ruby, this is not as true, of
> course, and class methods are just instance methods of a different kind of
> object. When you're using them as such, opening up that object with class <<
> self is a good idea. If you're not, then you shouldn't have very many of
> them and wouldn't need to refactor them out.
I consider classes & modules to be objects and therefore subject to
the rules of OOP. That one of the reasons why I love Ruby. The only
thing they have in common with global functions is that they are
easily accessible from anywhere in the process. Nonetheless, module
methods have encapsulated state.
Code evolves and things change. We usually don't set out to overload
one object with too much responsibility. It happens with incremental
I find that using class << self makes it easy to identify, even when
I'm not looking for, the opportunity to extract an object. Usually
this has to do with the same state being passed in as an argument.
>> I also like how all of the class << self methods are organized into a
>> single section. Yes, its difficult to read if it takes more than a
>> screenful, but I prefer it to having to track down all of the def
>> self.method_name methods spread all over the place.
> This is just a question of coding style. You can gather all your def
> self.foos in one place, and you can have multiple class << self sections
> (the latter being bad and the former good)
Thats true in theory, but in practice, I often see def
self.method_name spread all over the place and class << self in one
place. I'm not sure why, but I can guess that it has to do with not
thinking about object responsibility.
>> Also, class << self is more powerful. It allows you to use one way to
>> use your convenience methods (attr_*, include) and parser instructions
>> (public, private, protected). Nothing is worse than having to use both
>> def self.method_name and class << self.
> I agree with that. But I also believe in doing the simplest thing that could
> work, and using two extra lines of code when it's not necessary fails that
> test. If it is necessary, that's a different matter, of course.
Yes we all like YAGNI, but its a trade-off. We all have seen YAGNI
bite us in the ass too, especially when it means turning off the
brain. I don't think 2 extra filler lines of code make that strong of
an argument, when there is more than one class method (and even if
there is one class method IMO).
I think we also like how consistent conventions and delineation of
responsibility make code faster to read and understand.
> When I get back into work on Tuesday, I'll dig up what Matz says in RPL
> (unless someone else has a copy?)
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users