On Nov 25, 2008, at 1:27 PM, Wes G. wrote:
private
def self.blah
…
endto get private class methods, or does private not work on class
methods in this way?
You’ll have to open the metaclass:
Scott
On Nov 25, 2008, at 1:27 PM, Wes G. wrote:
private
def self.blah
…
endto get private class methods, or does private not work on class
methods in this way?
You’ll have to open the metaclass:
Scott
On Wed, Nov 26, 2008 at 8:23 AM, Shot (Piotr S.) [email protected]
wrote:
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.
Actually, instance variables in a “def self." method still refer to
the singleton object. The body of that method is treated just like a
method in “class << self”. You just don’t get a chance, as you say,
to make accessors with "attr_”, since that goes outside your method
definitions.
Peter
On Wed, Nov 26, 2008 at 5:23 AM, Shot (Piotr S.)
[email protected]wrote:
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.
Right. I was talking about the difference between using “class << self”
and
“def self.foo” when other things were equal. I do understand there are
situations (like the one you mention) where it’s handy to be actually in
the
eigenclass when defining methods.
///ark
On Wed, Nov 26, 2008 at 6:51 AM, Matt W. [email protected] wrote:
That’s one of the things that attracted me to using class << self to
contain all these methods - it just seemed easier to me to visualise what
was going on.
That makes sense. If you’re doing things where being inside the
eigenclass
helps, then by all means open the eigenclass. I think I and others were
just
commenting on it being a default style for some programmers (and I went
on
to snarkily speculate on some of their motives).
I’d be really interested to know the nature of the criticisms made about
it
in the Matz book Mark mentioned.
I’ll have a peep when I get in to work today. Of course, it’s hard to
tell
what are Matz’s opinions and what are Flanagan’s (who’s not a major
light in
the Ruby world, by any means). Basically, I think his/their objections
were
the ones I’ve used: it’s just not necessary in most cases. It’s also
different from the way class methods are defined in C++, Java, and C#.
But
sometimes it’s useful.
///ark
On 26 Nov 2008, at 14:38, Peter J. wrote:
method in “class << self”. You just don’t get a chance, as you say,
to make accessors with “attr_*”, since that goes outside your method
definitions.Peter
That’s one of the things that attracted me to using class << self to
contain all these methods - it just seemed easier to me to visualise
what was going on.
I’d be really interested to know the nature of the criticisms made
about it in the Matz book Mark mentioned.
cheers
Matt
On Wed, Nov 26, 2008 at 8:23 AM, Shot (Piotr S.) [email protected]
wrote:
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).
I’ve never had trouble accessing class-level instance variables
(@variables) in class methods defined as “def self.foo”. In fact I
hardly ever use @@variables, and I never use class << self for
defining class methods.
–
Avdi
Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
On Wed, Nov 26, 2008 at 8:23 AM, Shot (Piotr S.) [email protected]
wrote:
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.
It’s true you need to use class << self to use attr_* macros, but not
true that you can’t use singleton instance variables otherwise:
class Foo
class << self
attr_accessor :class_var
end
def self.hello
puts "@class_var: #{@class_var}"
end
end
Foo.class_var = 42
Foo.hello
=> “@class_var: 42”
–
Avdi
Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
On Wed, Nov 26, 2008 at 8:47 AM, Avdi G. [email protected] wrote:
class << self
attr_accessor :class_var
end
Also, with Rails, you could do
cattr_accessor :class_var
which has the same readability benefits as ‘def self.foo’
///ark
On Wed, Nov 26, 2008 at 8:39 AM, Avdi G. [email protected] wrote:
In fact I hardly ever use @@variables
And class variables are problematic in Rails in development mode because
of
class reloading.
///ark
On 26 Nov 2008, at 16:51, Mark W. wrote:
On Wed, Nov 26, 2008 at 8:39 AM, Avdi G. [email protected] wrote:
In fact I hardly ever use @@variables
And class variables are problematic in Rails in development mode
because of class reloading.
And more generally dangerous for threading reasons, right?
cheers,
Matt
Avdi G. wrote:
very, very good reason. I can’t think of the last time I had that
good a reason.
So… you are saying that this is preferred:
class State < AR:Base
def self.names
@names ||= State.all.map{|s| s.name}
end
end
to this:
class State < AR:Base
def self.names
@@names ||= State.all.map{|s| s.name}
end
end
Is that correct?
How is using a class instance variable safer from a threading point of
view? Do threads not share class instance variables the same way class
variables would be shared?
-Ben
On Wed, Nov 26, 2008 at 12:17 PM, Matt W. [email protected] wrote:
And class variables are problematic in Rails in development mode because
of class reloading.And more generally dangerous for threading reasons, right?
All of the above. My rule of thumb is: don’t use them unless I have a
very, very good reason. I can’t think of the last time I had that
good a reason.
–
Avdi
Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
Everyone seems to agree on the basic issues, but are coming at it from
different viewpoints.
The question, then, should be: which of these patterns (class << self
or self.method) encourages/discourages good behaviors?
As I’ve hinted, Ruby itself is a bad example. So is Rails. I’m
beginning to wonder, however, if this is not necessarily the case for
languages and large frameworks.
What class is this? The detractors of class << self appear to me to
be ignoring the fact that many files have multiple classes defined
therein. If I’m looking at a group of methods in a file, I NEVER know
which class I’m in until I search backwards for the “class” token.
(So keep the token “class” out of your comments & docs) self.method
doesn’t do much to help this.
But XP extremists argue that a class should never be bigger than a
couple of pages in the first place. Maybe that is the real problem.
I prefer class << self as it seems to aid refactoring and looks
cleaner.
YMMV
On Wed, Nov 26, 2008 at 8:46 PM, Ben M. [email protected] wrote:
class State < AR:Base
would be shared?
AFAIK it isn’t any safer from a threading point of view.
My biggest hate of class variables is that they are shared throughout
an entire inheritance hierarchy (and I do not find @@ aesthetically
pleasing). Class instance variables are not.
class A
def self.foo
@@foo
end
def self.foo=a
@@foo = a
end
end
class B < A ; end
class C < B ; end
A.foo = 1
A.foo # => 1
C.foo # => 1
C.foo = 10
C.foo # => 10
A.foo # => 10 – surprise!
Class instance variables don’t have this problem.
class A
def self.foo
@foo
end
def self.foo=a
@foo = a
end
end
class B < A ; end
class C < B ; end
A.foo = 1
A.foo # => 1
C.foo # => nil
C.foo = 10
C.foo # => 10
A.foo # => 1
–
Zach D.
http://www.continuousthinking.com
On Tue, Nov 25, 2008 at 8:41 AM, Matt W. [email protected] 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?
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.
Its too easy to confuse because it reads like its in the same instance,
def self.foobar
@foobar
end
def foobar
@foobar
end
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
way.
class Foo
def self.method_1(an_instance)
end
def method_1
end
def method_2
end
def method_3
end
def self.method_2(an_instance)
end
end
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.
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.
Student [email protected] writes:
therein. If I’m looking at a group of methods in a file, I NEVER know
which class I’m in until I search backwards for the “class” token.
You do if you use a good editor, like emacs
Pat
On Thu, Nov 27, 2008 at 1:59 PM, Brian T.
[email protected]wrote:
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.
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
way.
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 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)
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.
When I get back into work on Tuesday, I’ll dig up what Matz says in RPL
(unless someone else has a copy?)
///ark
On Thu, Nov 27, 2008 at 4:40 PM, Brian T.
[email protected]wrote:
When maintaining code, I often wish I could travel back in time and
tell the writer “Don’t do that”.
I don’t see how we can solve the problem of people not following style
guidelines by giving them another style guideline to follow.
module methods have encapsulated state.
Probably 99% of the (non-framework) class methods I’ve seen have no
state.
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).
If writing those two lines of code are unnecessary for any of the uses
you
and others have described, I would call that turning off the brain.
I think we also like how consistent conventions and delineation of
responsibility make code faster to read and understand.
Agreed, but I think this begs the question under discussion.
///ark
(For those who are tired of this non-RSpec-related discussion (but
apparently find themselves forced to read it), I really will try to wrap
up
my contribution. I don’t have the time for the Ruby list, so this is the
only place I have to talk about fun stuff like this. ObRSpec: the
discussion
did illuminate a situation where tests can pass but the development app
can
fail - when using class variables in RoR.)
On Thu, Nov 27, 2008 at 7:58 PM, Mark W. [email protected] wrote:
On Thu, Nov 27, 2008 at 4:40 PM, Brian T. [email protected]
wrote:When maintaining code, I often wish I could travel back in time and
tell the writer “Don’t do that”.I don’t see how we can solve the problem of people not following style
guidelines by giving them another style guideline to follow.
Honestly, I’m not going to get my panties in a bunch if I see code
with def self.method_name in it. I don’t care what you do with your
code, unless I need to maintain it.
If there are problems with the code, I’ll consolidate these methods
into a class << self block so I can have a better understand over what
is going on.
I think that if we were going to follow a style guideline, class <<
self is more consistent. It leaves less decisions to the programmer,
less opportunity to make things messy, and is more powerful. Some
people have a harder time grasping nesting and some people have a
harder time with less consistent code. Choose your poison.
module methods have encapsulated state.
Probably 99% of the (non-framework) class methods I’ve seen have no state.
Thats interesting. I can’t give you a percentage, but I often either
see state, class methods referencing other class methods (which gets
very confusing with def self.method_name btw) and passing along the
same arguments.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).If writing those two lines of code are unnecessary for any of the uses you
and others have described, I would call that turning off the brain.
I just explained that its a trade-off, so you can choose to ignore the
trade-off. I’ll let you think about that one.
I suppose that we can write our entire program with one LOC. I suppose
thats following YAGNI. Hell, why use do end? Its two extra lines of
code all over the place.
We can also remove lines of code by using ; everywhere. No more
newlines. AwesomeI think we also like how consistent conventions and delineation of
responsibility make code faster to read and understand.Agreed, but I think this begs the question under discussion.
I don’t follow. Can you clarify?///ark
(For those who are tired of this non-RSpec-related discussion (but
apparently find themselves forced to read it), I really will try to wrap up
my contribution. I don’t have the time for the Ruby list, so this is the
only place I have to talk about fun stuff like this. ObRSpec: the discussion
did illuminate a situation where tests can pass but the development app can
fail - when using class variables in RoR.)
Yeah, state in class
On Thu, Nov 27, 2008 at 5:12 PM, Brian T.
[email protected]wrote:
I suppose that we can write our entire program with one LOC. I suppose
thats following YAGNI. Hell, why use do end? Its two extra lines of
code all over the place.
That’s not YAGNI. We need clarity now - there’s no ‘gonna’ about it.
I
was responding to the idea that we should always use class << self in
case
we need the construct later.
I think we also like how consistent conventions and delineation of
responsibility make code faster to read and understand.Agreed, but I think this begs the question under discussion.
I don’t follow. Can you clarify?
I just thought the statement above assumes the issues in contention in
order
to bolster its argument. It assumes that using def self.foo is not a
consistent convention and doesn’t delineate responsibility. That’s not a
given - it’s one of the things we’re discussing.
///ark
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs