Class << self considered harmful... really?


#1

Sorry, I know this is off-topic, but I’d really like to know what the
revered ruby-hackers who read this list think.

See
http://ozmm.org/posts/class__self_is_harmful.html

I have adopted class << self, partly from reading RSpec and Cucumber’s
code as I learn Ruby. I personally think of class methods (or ‘static’
methods) as being in a kind of ‘holding pen’ waiting to be factored
off onto a proper class of their own, so I rather like the clear way
you can group them in a ‘nameless’ metaclass ready for the exit door.

I also really like the clarity of seeing the invisible metaclass for
what it is.

What do people think? How can this be harmful?

cheers,
Matt


#2

On Tue, Nov 25, 2008 at 8:41 AM, Matt W. removed_email_address@domain.invalid wrote:

‘nameless’ metaclass ready for the exit door.

I also really like the clarity of seeing the invisible metaclass for what it
is.

What do people think? How can this be harmful?

I think the issue is that people are using class << self to access the
virtual class when they don’t need it. I’ve seen code where you have
to scroll to see all of the methods implemented inside of class <<
self. Adding methods to a virtual class does make method dispatching
in ruby less efficient, but I don’t think enough to render it
non-usable.

The virtual class of an object (class or instance alike) gives you the
ability to modify the object in ways that a simple class method
usually does not allow. For example, if you want to break down a class
method into a couple of methods, but you don’t want to support all of
the methods as a public API. Here you can use class << self to
privately scope some of those helper methods that you just decomposed.

My rule of thumb is to use it when I can’t easily achieve the same
result using other mechanisms, but not to use it just cause’.


Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com


#3

On Tue, Nov 25, 2008 at 9:38 AM, Zach D. removed_email_address@domain.invalid
wrote:

class of their own, so I rather like the clear way you can group them in a
‘nameless’ metaclass ready for the exit door.

I also really like the clarity of seeing the invisible metaclass for what it
is.

What do people think? How can this be harmful?

I forgot to add it is considered harmful because it can so easily be
abused and make readability of the code very difficult to understand.
Especially when doing meta-meta programming. :slight_smile:

usually does not allow. For example, if you want to break down a class
http://www.mutuallyhuman.com


Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com


#4

On Tue, Nov 25, 2008 at 8:39 AM, Zach D. removed_email_address@domain.invalid
wrote:

as being in a kind of ‘holding pen’ waiting to be factored off onto a proper
Especially when doing meta-meta programming. :slight_smile:
ability to modify the object in ways that a simple class method
usually does not allow. For example, if you want to break down a class
method into a couple of methods, but you don’t want to support all of
the methods as a public API. Here you can use class << self to
privately scope some of those helper methods that you just decomposed.

My rule of thumb is to use it when I can’t easily achieve the same
result using other mechanisms, but not to use it just cause’.

One thing Chris points out in his blog is that ‘def self.method_name’
is perfectly fine, and that it makes refactoring easier. My experience
is different, because I’m often searching for methods with ‘dev
method_name’ - this is actually one of the reasons I have preferred
‘class << self’.

That said, I’m all for speeding things up where we can, so I’ll be
looking into this in rspec. I just found 22 uses of ‘class << self’ in
rspec. Sometime soon I’ll see how many of them I feel I can get rid
of.

Cheers,
David


#5

On Tue, Nov 25, 2008 at 9:38 AM, Zach
Dennis removed_email_address@domain.invalid wrote:

The virtual class of an object (class or instance alike) gives you
the ability to modify the object in ways that a simple class method
usually does not allow.

In particular, when implementing a singleton this way, it’s possible to
access instance variables of the singleton (rather than having to work
on class variables).

My rule of thumb is to use it when I can’t easily achieve the
same result using other mechanisms, but not to use it just cause’.

Ditto. I basically use it for singleton classes (Log, Config) only.

David C.:

One thing Chris points out in his blog is that ‘def self.method_name’
is perfectly fine, and that it makes refactoring easier. My experience
is different, because I’m often searching for methods with ‘def
method_name’ - this is actually one of the reasons I have preferred
‘class << self’.

PHP with its ‘function &returningAReference(…)’ syntax taught me to grep
for function.*name, so I now simply grep for def.*method_name in Ruby
(granted, it doesn’t work too well if you have other methods with
‘method_name’ inside their names).

– Shot


#6

On Tue, Nov 25, 2008 at 5:41 AM, Matt W. removed_email_address@domain.invalid wrote:

‘nameless’ metaclass ready for the exit door.

The nature of class methods in Ruby (as instance methods of the class’s
eigenclass) is for most purposes an implementation detail. It adds
nothing
to understanding to open the eigenclass inside the class’s definition in
order to add class methods. It may save some typing, and it does help
when
searching (as David) says. Nevertheless, I regard the practice as a bit
of
an affection - ‘look at me, ma, I’m opening the eigenclass!’ - or as the
imitation of an affection. It confuses newbies to no purpose, and
confuses
everyone when ‘class << self’ has scrolled off the top of the screen.

It’s recommended against in The Ruby P.ming Language (of course,
there
are exceptions to every rule).

///


#7

On Tue, Nov 25, 2008 at 11:08 AM, Mark W. removed_email_address@domain.invalid wrote:

methods) as being in a kind of ‘holding pen’ waiting to be factored off onto
everyone when ‘class << self’ has scrolled off the top of the screen.
A lot of things confuse newbies. I don’t think that’s a very good
point for why you don’t do something. #each confuses newbies, should
we also refrain from using that? Of course not.

Educating people so they understand why and when it should be avoided
is better then raising a fire alarm (unless it’s really a fire).
Contrary to your statement though, I don’t use class << self to feel
special, and my ma could care less about how I code. :wink:


Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com


#8

On 25 Nov 2008, at 16:48, Pat M. wrote:

can group
searching (as David) says. Nevertheless, I regard the practice as
we also refrain from using that? Of course not.
def methdod2; end
def methdod3 end
def methdod4; end
end

becomes confusing as soon as those method definitions fill up a
screen.
def self.method1 makes it instantly clear that it’s a singleton
method.
That’s what I do and why I do it, anyway.

Surely, as soon as they scroll off the screen, it’s time to factor
that code off into a module or class of its own though?

It seems to me like whenever you have a lot of class methods on a
class, you’ve got a new class dying to get out. It’s like class <<
self is like a little incubator for that new type!

Or Is that just me?


#9

“Zach D.” removed_email_address@domain.invalid writes:

code as I learn Ruby. I personally think of class methods (or ‘static’
imitation of an affection. It confuses newbies to no purpose, and confuses
everyone when ‘class << self’ has scrolled off the top of the screen.

A lot of things confuse newbies. I don’t think that’s a very good
point for why you don’t do something. #each confuses newbies, should
we also refrain from using that? Of course not.

Educating people so they understand why and when it should be avoided
is better then raising a fire alarm (unless it’s really a fire).
Contrary to your statement though, I don’t use class << self to feel
special, and my ma could care less about how I code. :wink:

I thought it was just that

class << self
def method1; end
def methdod2; end
def methdod3 end
def methdod4; end
end

becomes confusing as soon as those method definitions fill up a screen.
def self.method1 makes it instantly clear that it’s a singleton method.
That’s what I do and why I do it, anyway.

Pat

p.s. using class << self to show off is weak if you’re just defining
class methods. Use it on an instance and then send(:define_method) for
some real points!


#10

On Tue, Nov 25, 2008 at 8:34 AM, Zach D. removed_email_address@domain.invalid
wrote:

Nevertheless, I regard the practice as a bit of
an affection - ‘look at me, ma, I’m opening the eigenclass!’ - or as the
imitation of an affection. It confuses newbies to no purpose, and
confuses
everyone when ‘class << self’ has scrolled off the top of the screen.

A lot of things confuse newbies. I don’t think that’s a very good
point for why you don’t do something.

I believe potential confusion is a good argument against something,
ceteris
paribus. However, as I indicated at the end of my message, ceteri are
not
always paribi. In other words, we all do things that would confuse
newbies,
but (like #each) they have obvious benefits. That’s why we use them.

Educating people so they understand why and when it should be avoided

Well, sure, but I’m just talking about cutting some code, here, not
writing
a blog article.

is better then raising a fire alarm (unless it’s really a fire).

Contrary to your statement though, I don’t use class << self to feel
special, and my ma could care less about how I code. :wink:

Sorry! I didn’t mean to seem like I was addressing you personally, Zach.
In
fact, I was thinking of a blog entry I read the other day where a single
method was enclosed in ‘class << self.’ The only reason I could think of
for
that was 1) because it looked cool to the author, or 2) he thought it
would
look cool to others. It just looked like a couple of lines of wasted
space
to me.

I don’t know about any fire alarms - I think the important thing to
consider
is what benefits the practice has. In most cases I’ve seen, there aren’t
any, and it does have the disadvantages I mentioned.

///ark


#11

On Tue, Nov 25, 2008 at 8:54 AM, Matt W. removed_email_address@domain.invalid wrote:

Surely, as soon as they scroll off the screen, it’s time to factor that
code off into a module or class of its own though?

That’s assuming there are a lot of class methods. There might be only
one,
but if that ‘class << self’ is off the screen, there’s the potential for
confusion (among noobs and gurus alike). In many if not most cases I’ve
seen, there were no counterbalancing benefits.

For more, see The Ruby P.ming Language for their take.

///ark


#12

On Tue, Nov 25, 2008 at 8:41 AM, Matt W. removed_email_address@domain.invalid wrote:

Sorry, I know this is off-topic, but I’d really like to know what the
revered ruby-hackers who read this list think.

See
http://ozmm.org/posts/class__self_is_harmful.html

For the case of defining class methods I completely agree. It’s
unnecessary and it makes classes harder to read, because you have to
scroll back just to determine whether you’re looking at class or
instance methods. Just type “def self.foo()”. It’s not that hard.


Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com


#13

On 25 Nov 2008, at 17:54, Mark W. wrote:

On Tue, Nov 25, 2008 at 8:54 AM, Matt W. removed_email_address@domain.invalid
wrote:

Surely, as soon as they scroll off the screen, it’s time to factor
that code off into a module or class of its own though?

That’s assuming there are a lot of class methods. There might be
only one, but if that ‘class << self’ is off the screen, there’s the
potential for confusion (among noobs and gurus alike). In many if
not most cases I’ve seen, there were no counterbalancing benefits.

I don’t understand. If it’s off the screen, it’s off the screen,
whether it’s defined using self.foo or class << self; def foo; end;

What have I missed?

For more, see The Ruby P.ming Language for their take.

I didn’t know about that book! Cheers for the recommendation :slight_smile:


#14

On Tue, Nov 25, 2008 at 12:51 PM, Mark W. removed_email_address@domain.invalid wrote:

point for why you don’t do something.

is better then raising a fire alarm (unless it’s really a fire).
Contrary to your statement though, I don’t use class << self to feel
special, and my ma could care less about how I code. :wink:

Sorry! I didn’t mean to seem like I was addressing you personally, Zach.

I didn’t think you were. Did my wink-smily not come through?

///ark


Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com


#15

On Tue, Nov 25, 2008 at 10:04 AM, Matt W. removed_email_address@domain.invalid wrote:

confusion (among noobs and gurus alike). In many if not most cases I’ve
seen, there were no counterbalancing benefits.

I don’t understand. If it’s off the screen, it’s off the screen, whether
it’s defined using self.foo or class << self; def foo; end;

If the def line is off the screen, then you don’t even know what method
you’re in (at least with most editors). I wasn’t talking about that.

Look, all I’m saying is that to understand the meaning of a chunk of
code,
you need to see more lines with ‘class << self’ that without it.
Personally,
I like relatively terse code, because it’s easier to read - if for no
other
reason than that more fits on a single screen without losing clarity.

I’d be interested, however, in hearing about the benefits of opening the
eigenclass to define class methods (apart from ease in searching, which
may
be best handled with ctags).

///ark


#16

On Nov 25, 2008, at 1:14 PM, Mark W. wrote:

about that.

Look, all I’m saying is that to understand the meaning of a chunk of
code, you need to see more lines with ‘class << self’ that without
it. Personally, I like relatively terse code, because it’s easier to
read - if for no other reason than that more fits on a single screen
without losing clarity.

I’d be interested, however, in hearing about the benefits of opening
the eigenclass to define class methods (apart from ease in
searching, which may be best handled with ctags).

Grouping and private methods.

You won’t risk having a class methods scattered all over the file.

Scott


#17

Scott T. wrote

I’d be interested, however, in hearing about the benefits of opening
the eigenclass to define class methods (apart from ease in searching,
which may be best handled with ctags).

Grouping and private methods.
Potentially dumb question:

As far as private class methods, could you do

private
def self.blah

end

to get private class methods, or does private not work on class methods
in this way?

Wes


#18

Matt W. removed_email_address@domain.invalid writes:

the
factored off onto
order to add class methods. It may save some typing, and it does
A lot of things confuse newbies. I don’t think that’s a very good
class << self
That’s what I do and why I do it, anyway.


rspec-users mailing list
removed_email_address@domain.invalid
http://rubyforge.org/mailman/listinfo/rspec-users

Just you :slight_smile: Bad style is not an excuse for bad style.

Pat


#19

On Tue, Nov 25, 2008 at 10:27 AM, Wes G. removed_email_address@domain.invalid wrote:

You would do

def self.blah
#…
end
private_class_method :blah

///ark


#20

Mark W.:

I’d be interested, however, in hearing about the benefits of opening
the eigenclass to define class methods (apart from ease in searching,
which may be best handled with ctags).

Such methods have access to the eigenclass’s instance variables, and so
class << self works very nice when working with singletons (like Log or
Config).

If you don’t use class << self, you have to work on class variables and
you can’t use the attr_* shorthands to access the singleton’s variables.

– Shot