Accessing class instance variables from an instance?

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 example

You 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. :wink:

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. :slight_smile: 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. :slight_smile:

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. :wink:

···

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:

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. :wink:

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. :slight_smile: 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).

A better alternative would be to do this:

class Object
  def my_class; self.class end
end

Then you do not need to do

Foo.bar
self.class.bar

but instead you can do

my_class.bar

which seems a lot clearer to me while avoiding the nasty "self.class".
Maybe someone else can think of a better (presumably: shorter) name
than #my_class.

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.

I guess my main point is that making a method call appear to be on the
local instance which in fact is done on another instance is
misleading. For the reader it is better to at least signal that #foo
is not invoked on self but rather on another instance. For that you
need a method or a variable reference.

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.

We differ in the estimation about the distribution of useful and
harmful. I'd say obfuscating a method is invoked on another instance
does more harm than good so the default should be to not make it too
easy. This forces people to know what they are doing when they do it.
As an example: you can modify instance variables of another instance
but it is deliberately made clumsy (#set_instance_variable etc.)
although possible.

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. :slight_smile:

That's the point: OO is mostly about the state of instances and its
changes. Everything that helps keep clear what's happening is good
IMHO.

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.

There are no technical obstacles here defining instance methods which
access class state. I just happen to believe that the tradeoff fall
on the side that we do not want to have such a feature because the
convenience of the writer is the pain of the reader of the code.

All IMHO.

+1

PS. Wow, that message was a bit longer than I had planned. :wink:

:slight_smile:

Kind regards

robert

···

On Thu, Dec 22, 2011 at 2:09 AM, Garthy D <garthy_lmkltybr@entropicsoftware.com> wrote:

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

Hi 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. :wink:

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. :slight_smile: 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).

A better alternative would be to do this:

class Object
   def my_class; self.class end
end

Then you do not need to do

Foo.bar
self.class.bar

but instead you can do

my_class.bar

which seems a lot clearer to me while avoiding the nasty "self.class".
  Maybe someone else can think of a better (presumably: shorter) name
than #my_class.

I like that. I hadn't thought of it myself- it's one of those "of course, it's so obvious!" type things, which leaves you wondering why you didn't think of it yourself. :wink:

I have to admit a guilty pleasure of mine is adding the occasional method to "Object" in Ruby, and I could see myself adding such a thing to "Object". But I shall have to keep such impure thoughts away from the list. :wink:

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.

I guess my main point is that making a method call appear to be on the
local instance which in fact is done on another instance is
misleading. For the reader it is better to at least signal that #foo
is not invoked on self but rather on another instance. For that you
need a method or a variable reference.

There are definitely cases where the additional information (ie. that it is not being performed on the local instance) is vitally important. I am just saying that there are also cases where it is not. It is important to emphasise that I'm not saying only one case exists or one is more important than the other. Anyway, the question becomes: Whose responsibility is it to ensure that in these cases that it is properly emphasised? Is it the responsibility of the language to ensure these cases are always handled correctly by enforcing it through the language, or should the language step back, and leave it to the user to write either good or bad code?

I suspect that when designing a language you would come up across a lot of these sorts of choices. C++ requires impressive template gymnastics to pass a single generic parameter- type safety through fear of daunting pain. :wink: Python makes whitespace syntactically significant; pretty code whether you like it or not. :wink: C++ uses operator overloading for ease of expression, Java disallows it to avoid difficult to follow code. A good case could be made to either allow, or forbid, the exact same feature in this case. I think the problem we are talking about is that kind of thing.

I guess that personally I err on the side of giving the user the means to shoot themselves in the foot, if they really want to, provided that you don't set things up so that they can accidentally do it. Perhaps in this case it would be something like this:

class Foo

def self.bar *args
   whatever *args
end

attr_class_method_from_instance :bar

def baz
   one
   bar 2,4
   two
   bar 6 if three
   four
   bar 7
end

Working on the assumption for now that allowing class methods to be called implicitly from an instance is bad (it's probably easiest just to assume this for now), then we only allow a user to go for the foot shot (calling a class method for an instance) if they've explicitly requested it.

I would hate to be forced to, for example, write:

def baz
   one
   self.class.bar 2,4
   two
   self.class.bar 6 if three
   four
   self.class.bar 7
end

Because it draws attention toward the instance versus class method distinction, which simply may not be the most important thing in this context.

(Of course, the "self.class.bar" call could be wrapped in an "abar" wrapper, which might help to make it more understandable, or use the my_class shortcut you suggested above)

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.

We differ in the estimation about the distribution of useful and
harmful. I'd say obfuscating a method is invoked on another instance
does more harm than good so the default should be to not make it too
easy. This forces people to know what they are doing when they do it.

I think this touches on the safety aspect I mentioned above. I think we would agree that powerful but dangerous techniques should require deliberate actions to trigger, to avoid them being used inadvertently. We might differ on some of the details but I think we have similar motivations here.

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. :slight_smile:

That's the point: OO is mostly about the state of instances and its
changes. Everything that helps keep clear what's happening is good
IMHO.

Personally, I'd adjust that to say that everything that causes the behaviour to become clearer is good to include, but I would exclude unnecessary detail that does not add to the understanding, and *especially* leave out unnecessary verbiage that draws attention away from what is most important in that context. I would say that sometimes being explicit is beneficial, but sometimes it is not, and sometimes it has the opposite effect. Again, all IMHO. :slight_smile:

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.

There are no technical obstacles here defining instance methods which
access class state.

Ah, sorry, I did not explain properly. I mean, if there are any technical reasons for which a class method of a certain name (say, "bar") could not be easily triggered when an instance method of the same name (eg. "bar") is invoked. Perhaps, for example, it isn't easy to ensure without complicating calls or adding some sort of instance method proxy, which might not be desirable? I'm basically just saying that there might be a tech blocker here that I'm unaware of which could actually be the main reason behind the behaviour.

I just happen to believe that the tradeoff fall
on the side that we do not want to have such a feature because the
convenience of the writer is the pain of the reader of the code.

I would say that if you get the wrong person writing the code, no framework of restrictions can prevent them from writing terrible code. Such people always find a way, somehow. :wink: The right developer instead could emphasise such a thing, if it is important in the context. And anyway, I would argue, why hold back the better developers for the sake of the ones that cannot write easy-to-understand code?

Anyway, these are just a few more rambling evening thoughts from someone who should probably be getting a bit of sleep soon. :wink: I hope they are useful, even if it's nothing more than just a different perspective on the problem.

Garth

···

On 22/12/11 21:11, Robert Klemme wrote:

On Thu, Dec 22, 2011 at 2:09 AM, Garthy D > <garthy_lmkltybr@entropicsoftware.com> wrote:

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).

A better alternative would be to do this:

class Object
def my_class; self.class end
end

If self.class.whatever is bothering you, the _better_ alternative is
to just drop the self.

class Whatever
   def something_with_class
     class.something
   end
end

rather than

self.class.something

You didn't try that, did you? This does not even compile!

Cheers

robert

···

On Thu, Dec 22, 2011 at 1:52 PM, Steve Klabnik <steve@steveklabnik.com> wrote:

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).

A better alternative would be to do this:

class Object
def my_class; self.class end
end

If self.class.whatever is bothering you, the _better_ alternative is
to just drop the self.

class Whatever
def something_with_class
class.something
end
end

rather than

self.class.something

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

Argh, I always do this. It thinks it's a keyword. Derp.