Hi Robert and Josh,
Yeah, sorry, it was late. The need I actually come across isn't state
based, but functionality based. For example, HTTParty's get method. From
outside it's nice to be able to say `HTTParty.get(...)` but from inside
they don't want to have to say `self.class.get(...)` so that is an exampleYou can also say HTTParty.get(...) inside instance methods.
of a class level method that should be available to instances without
having to go find the class. I find that need occasionally. Or sometimes
I'm looking at some method and realizing it really could be a class method,
and that no one can use it without instantiating, but it's pretty obnoxious
to have to instantiate a class just to call some method that doesn't depend
on instances.Well, then make it a class method. That has the added advantage that
you make the call explicit in instance methods which use it and it is
immediately clear that this method does not manipulate instance state.I think this make-a-class-method-be-callable-as-instance-method looks
convenient on first sight but on second sight it may just be
obfuscation.Kind regards
robert
I've run into this kind of thing before, and it does impact me regularly. Having said that, I know my C++ background (which allows this) biases me somewhat on the issue.
I tend to steer away from "Foo.bar" style calls inside class Foo for the following reason- it complicates refactoring. If you determine that a class would benefit from being split (perhaps because another class has common functionality and you want it to share a common base), then you have to selectively rename all of the calls you have made to point to the correct class. Sure, it's not hard, and doesn't take too long, but when you're refactoring something for the sake of something else you have developed, not having to deal with additional chores to make it work makes it less likely that you'll stuff something up in the process. A similar problem arises with renaming the class, but admittedly the solution tends to be far easier.
For that reason, I'd instead use "class.bar" calls, if it were possible, which it is not, which brings us to "self.class.bar". I do this as you can't always tell ahead of time when you'll need to refactor something to pull out a base class, and so I'll assume that (almost) all of the classes I work on could be subject to such changes later in its lifetime. If you could tell beforehand, you would have designed it that way in the first place. Now, if you have a class method that is used both inside and out, but mostly inside (and regularly), it's a pain to have to write "self.class.bar" each time you want to call "bar". Incidentally, for "bar", I have a specific method in mind for something I have been working on (ie. a real-world problem), that makes the most sense as a class method, since it works entirely off the arguments and carries no state. The call in question has very specific structured input requirements, and is called extremely frequently inside the class, and occasionally outside.
In my case, I ended up solving it by adding an "abar" method that just called "self.class.bar", although using it that way does feel a bit silly, and makes the code less readable (an observer might ask what the difference between "bar" and "abar" is, for example).
Anyway, I just thought I'd share my particular experience. It's not hard to work around, but there are definitely good reasons to want to make it work that way. It falls under the area of a "quirk" for me, but that is of course just my personal experience based on my personal experience.
> That has the added advantage that
> you make the call explicit in instance methods which use it and it is
> immediately clear that this method does not manipulate instance state.
There are definitely cases where this could be advantageous, but there are also cases where this is not necessary or desirable. In general, I would personally say that if a particular mechanism is sometimes beneficial, but sometimes not, it is better to leave it up to the person writing the code to emphasise the mechanism where it is appropriate, and de-emphasise where it is not. For example, sometimes it is beneficial to be specific about the particular class of an object (or its capabilities), but would that justify requiring every method call to be prefixed by the class name, every time? I would say not. There are times where being specific about it would be beneficial, but in the remaining cases it would clutter up the code unnecessarily.
I think in the situation I outlined above, and possibly also in Josh's case, it falls in the realm of clutter. This does not, of course, take away from the fact that in some situations it would be important, or absolutely essential, to explicitly convey that the instance state will not be manipulated. I know that I have certainly run into this case as well- I won't bother with a personal anecdote as I suspect you also already know of many cases where it is extremely beneficial already.
I guess what I am saying is that if something is sometimes beneficial, and sometimes detrimental, that enforcing it is not always the best idea, but providing an optional means to make it explicit is beneficial. I do not believe that is a good idea in general to either force a mechanism that is only sometimes useful, or argue that as the mechanism is sometimes important, that having a means to conveniently avoid the mechanism when it is detrimental is not justified. There are of course always all sorts of tradeoffs when designing a language- perhaps the particular feature Josh and I would find beneficial is not readily possible for some technical reason.
All IMHO.
Garth
PS. Wow, that message was a bit longer than I had planned.
···
On 22/12/11 00:49, Robert Klemme wrote:
On Wed, Dec 21, 2011 at 3:08 PM, Josh Cheek<josh.cheek@gmail.com> wrote: