Class variables, instance variables, singleton; Ruby v. C++

>> But see (3), below.
>>
>>
>>
>> (3)
>> class F
>> def sub1
>> @@x = 1
>> end
>> end
>>
>> class G
>> self.sub1
>> @@x=2
>> end
>> end
>>
>> # Why? Didn't the interpreter "see" @@x in class F?
>> F.class_variables #

> Probably not, since you haven't called the function yet!

Didn't the interpreter parse it?

If I do
  class X
    def y
      xyzzy = 3++
    end
  end

then the interpreter/parser will complain immediately that there was a
syntax error even though the function method y was not executed.

Yes, syntax errors are caught immediately by parsing. But think of instance
variables as a hash associated with the object and it might be more clear. For
example, if you did this:

SomeHash = {}
def foo
  SomeHash[:x] = :y
end

Would you expect SomeHash[:x] to exist just because you defined that method?

Now, I don't know whether instance variables are _actually_ implemented as a
hash. It might well be something much more efficient, but it behaves like a
hash, so that makes sense.

Also, consider: The method in question may _never_ be called. Why should Ruby
bother to create a variable that may never be used? That would be just as
foolish as implying that SomeHash[:x] exists before foo is called in my
example above. Sure, you could create it and set it to nil, but that'd be
pointless.

In C++, instances have access to the static variables and functions of
the class.

They don't inherit it ... but merely have access to it as if they
inherited it.

Instances indeed get access to class variables associated with that instance,
but again, class variables behave weirdly. But here's a quick example to help
clarify things:

SomeClass.new

Would you expect an object created that way to have a 'new' method of its own?
That is, would this make any sense:

SomeClass.new.new

Similarly, do the methods available at class creation time make any sense in
an object? For example, when creating a class:

class Foo
  attr_accessor :bar
end

You might think attr_accessor is a keyword. It isn't, it's just a method on
Class, so it's a class method on Foo.

There is no proper analog to "static functions" in C++, by the way -- they're
just methods on the class. But again, they aren't included into the instance
-- you access them on the class, just like you would with any other object.

So let me return to some simple examples that I hope make sense. Let's create
a counter for the number of instances that have been created.

class Foo
  def self.count
    @count
  end
  def self.increment_count
    @count ||= 0
    @count += 1
  end
end

This should be easy to understand. (If it's not, pretend I defined them
without self, and see if they make sense.)

Now, go define them, and play with them in irb. You wouldn't create any
instances of Foo yet, but you can do things like this:

Foo.count
Foo.increment_count
Foo.count
Foo.increment_count
Foo.increment_count
Foo.count

Go try that in irb, and see if the result makes sense.

Now let's move on. Keep the same class above, but add this -- if you're in the
same irb session, you can just re-open the class:

class Foo
  def initialize
    Foo.increment_count
  end
end

Now our counter should work as expected:

Foo.count
f = Foo.new
Foo.count

It won't tell you how many Foo objects actually exist. It's more a count of
how many have ever been created.

Cool.

Is there a way to tell how many instances actually exist? Is there
anything like a destructor for class instances? Just curious.

Also, if you understand this so far, go back to my earlier example that was
"way over your head" -- see if it makes sense. I'll give you an example -- if
you have a variable f, which is an instance of class Foo, what is f.class?

And if you're inside the initialize method of f, what is self? And what is
self.class?

> (There is a way to call private methods from outside, but I will leave
> you to find it out on your own. It's not generally a good thing, and
> I'm not going to hand you a dangerous tool until you understand when
not MLK> to use it.)

So ... when _can_ I use class_variable_get ???

You can use it whenever you want. When _should_ you use it?

Like instance_variable_get, it's designed for metaprogramming -- that is, when
you're trying to access a variable, but its name is dynamic.

I'll give you an example of when instance_variable_get might be used. Remember
attr_reader? (If not, look it up...) Now, for speed, attr_reader is defined
in C, but it can be defined in Ruby. Here's the obvious 'eval' solution:

class Module
  def attr_reader *names
    names.each do |name|
      eval "def #{name}; @#{name}; end"
    end
  end
end

But there are many reasons I dislike eval. Here's the solution I'd prefer:

class Module
  def attr_reader *names
    names.each do |name|
      var_name = :"@#{name}"
      define_method name do
        instance_variable_get var_name
      end
    end
  end
end

So, basically, the reason that instance_variable_get is private to
Module is that one does not wish make breaking encapsulation too easy?

I mean, it seems easy enough to break encapsulation by adding an
accessor, right?

I don't expect you to follow every detail here. The use of define_method is an
advanced topic already. Hopefully, though, the fact that you already know how
to use attr_reader should give you an idea of how that works.

Also, I don't really expect you to need any of this yet -- attr_reader,
attr_writer, and attr_accessor should already do everything you need.

This is, actually, very lucid. I had few problems following any of it.

Also ... I _did_ try (successfully, I hope) to follow every detail.

Many many thanks.

···

On Saturday 28 November 2009 08:43:30 am Ralph Shnelvar wrote:

This is the so-called "class instance variable", which is really just
"an instance variable that happens to belong to a Class object". It's
common to use the phrase "class instance variable", but it's just a
way of clarifying what you mean. There's no separate "class instance
variable" language-level construct.

So ... let's see if I get this.

class X
  # "equivalent" to C++'s
  # class X {
  # protected:
  # static sometype at_at_x = 3;
  # };
  @@x = 3

  # "equivalent" to C++'s
  # class X {
  # private:
  # sometype at_x;
  # X::X() {at_x =3;}
  # };
  # at_x is not "inheritable" since it is private.
  @x = 3

  # No equivalent notion in C++. It's just a temporary variable
  x = 3
end

- - - -

It appears to me that "class" is a jumble of two kinds of very
different semantics.

There is the notion of a class as a template for instances of the
class.

Then there is a very different notion of a sorta static class that
has it's own variables that do not propagate to instances; and may
(@@x) or may not (@x) propagate and be accessile to static subclasses inherited from
the static superclass.

A lot to wrap one's head around. I assume that there are good design
reasons to jumble these two concepts together in the semantics of
"class".

Ralph Shnelvar wrote
[...]

> (There is a way to call private methods from outside, but I will leave
> you to find it out on your own. It's not generally a good thing, and
> I'm not going to hand you a dangerous tool until you understand when
not MLK> to use it.)

So ... when _can_ I use class_variable_get ???

> You can use it whenever you want. When _should_ you use it?

> Like instance_variable_get, it's designed for metaprogramming --
that is, when
> you're trying to access a variable, but its name is dynamic.

> I'll give you an example of when instance_variable_get might be
used. Remember
> attr_reader? (If not, look it up...) Now, for speed, attr_reader is
defined
> in C, but it can be defined in Ruby. Here's the obvious 'eval'
solution:

> class Module
> def attr_reader *names
> names.each do |name|
> eval "def #{name}; @#{name}; end"
> end
> end
> end

> But there are many reasons I dislike eval. Here's the solution I'd
prefer:

> class Module
> def attr_reader *names
> names.each do |name|
> var_name = :"@#{name}"
> define_method name do
> instance_variable_get var_name
> end
> end
> end
> end

So, basically, the reason that instance_variable_get is private to
Module is that one does not wish make breaking encapsulation too easy?

I mean, it seems easy enough to break encapsulation by adding an
accessor, right?

Wrong. attr_accessor really doesn't break encapsulation in the
conventional sense -- that is, it's not even remotely equivalent to
declaring a public data member in C++ or Java. Ruby has *no way* to
make instance variables public. This is a Good Thing.

attr_accessor just defines getter and setter methods -- and keeps the
variable encapsulated. When you do
@p = Person.new
@p.name = 'Ralph'
puts @p.name

the caller is making no assumptions at all about whether @p has an
instance variable called @name. It is impossible to tell from the code
supplied -- that detail is completely encapsulated. We assume that @p
has methods called :name and :name= , but that leaks nothing of @p's
internals.

Best,

···

--
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org

> I don't expect you to follow every detail here. The use of
define_method is an
> advanced topic already. Hopefully, though, the fact that you already
know how
> to use attr_reader should give you an idea of how that works.

> Also, I don't really expect you to need any of this yet --
attr_reader,
> attr_writer, and attr_accessor should already do everything you
need.

This is, actually, very lucid. I had few problems following any of it.

Also ... I _did_ try (successfully, I hope) to follow every detail.

Many many thanks.

--
Posted via http://www.ruby-forum.com/\.

The reason that instance_variable_get exists is solely to allow dynamic
lookup of instance variables to work in cases like define_method. It is not
intended to be used from the outside, because it would unintentionally publish
all internal state of a class. This can be easily circumvented in such a
dynamic language like Ruby, but it has a big, fat warning sign attached to it.

But even from the outside, it doesn't break one of the main properties of the
ruby language: the uniform access principle. There is only one way to
retrieve or change a value from/in an Object: by calling a method.
C++ and Java have two: directly accessing a member or calling a method.
In Ruby, this is especially true, because:

   a.foo = "bar"

Is the same as sending the message :foo= to a.

   a.send(:foo=, "bar")

where foo= is implemented as:

   class A
     def foo=(val)
       #internal assignment
     end
   end

In every language it is easy to publish a value by adding a method. This
is not "breaking encapsulation", it is intentional publishing. If you don't
know what you are doing when implementing this method, no language can help
you. The way Ruby handles instance variables only makes it harder to access
them in ways that the class implementer intended.

But even with instance_variable_get public, your only way of getting a value
would still be to call that method. Which would give the class implementer
the possibility to delete, change or hook that method.

Regards,
Florian

[1]: Uniform access principle - Wikipedia
- --
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

···

On Nov 28, 2009, at 5:12 PM, Ralph Shnelvar wrote:

So, basically, the reason that instance_variable_get is private to
Module is that one does not wish make breaking encapsulation too easy?

I mean, it seems easy enough to break encapsulation by adding an
accessor, right?

> It won't tell you how many Foo objects actually exist. It's more a
count of DM> how many have ever been created.

Cool.

Is there a way to tell how many instances actually exist? Is there
anything like a destructor for class instances? Just curious.

These are separate questions.

In MRI, you can tell how many instances exist by actually counting them. Look
at the documentation for ObjectSpace.

And yes, you can register a destructor -- that's also in ObjectSpace, and it's
called a "finalizer". But remember, Ruby is garbage-collected -- that means
you have absolutely no guarantee of _when_ that object will be removed. The
finalizer is guaranteed to be called before the program exits, but that's the
only guarantee you get.

Both of these are relatively advanced topics, and something that shouldn't be
needed in most programs. Keep in mind that in C++, then main purpose of a
destructor is to free resources used by the object in question -- and most of
these resources are simply other objects. So, the fact that Ruby is garbage-
collected removes most of the reason for destructors/finalizers.

An exception would be a resource that is more than just an object -- for
example, an open file, or a database handle. But these are generally much
scarcer resources than memory, so if at all possible, you want to manually
close these as soon as you can, rather than waiting for something to get
garbage collected. For example:

open 'some_file' do |file|
  file.each_line do |line|
    # do some stuff with each line in the file
  end
end

What might not be obvious here is that the 'open' call will automatically
close the file when the block exits.

So, basically, the reason that instance_variable_get is private to
Module is that one does not wish make breaking encapsulation too easy?

Others have answered this already...

In a very basic sense, yes, that seems like a valid answer. There is really no
good reason why code outside a class should have to call
instance_variable_get, most of the time. It's private so that when you try,
you'll rethink your architecture so you don't need it.

On the other hand, Ruby has open classes. While there are ways to supposedly
lock it down and run untrusted code in a safe sandbox, in general, any code
running in the same interpreter can do all sorts of things to existing
classes. In other words, if you want to access the variable @bar in an object
of class Foo, you could always do something like this:

class Foo
  attr_reader :bar
end

There are many other ways of getting the same result.

Now, Florian mentioned another aspect, which is that you still can only know
anything about an object by calling methods on it. So even if
instance_variable_get was public, there's nothing from stopping an especially
paranoid class from redefining it or removing it.

I think that's more than enough to answer your question, but if you're
curious, you could always have a sort of "arms race" of trying to enforce
encapsulation. For example, even if someone redefines instance_variable_get, I
can always do this:

Class.instance_method(:instance_method).bind(Foo).call(:instance_variable_get).bind(foo).call(:@bar)

That means there's nothing the Foo class itself can do to hide the @bar
variable from you, including redefining instance_method on itself.

But wait! How do you know Class itself hasn't been modified?

The lesson to learn here is that while Ruby is very good at encapsulation by
convention, it's not very good at all at enforced encapsulation, as C++ is. At
the end of the day, you have to remember that this is a language which lets
you define null to be not null. Here, try this in irb:

class NilClass
  def nil?
    false
  end
end

Now type any other command, and watch irb crash.

I mean, it seems easy enough to break encapsulation by adding an
accessor, right?

Well, yes and no.

Yes, you can break encapsulation by just adding an accessor to any instance
variable that anyone was trying to hide from you. You can also break it by
using one of several tricks to call the private instance_variable_get, and
probably a few ways I haven't thought of. Ruby doesn't enforce encapsulation.

On the other hand, accessors are the ultimate in encapsulation -- partly
because they're the only sane way to get at instance variables, and partly
because they're so easy to define. I remember wishing for them in Java, where
good coding style led to lots of these:

private int foo;
public int getFoo() {
  return foo;
}
public void setFoo(int value) {
  foo = value;
}

I can see why Java people use tools like Eclipse -- there's no way you want to
type all that stuff yourself. But it's still a good idea, because it allows
you to change your internal structure to no longer require that variable,
without changing your external interface.

The point here is, if you actually expose an accessor, no one has to use
instance_variable_get or anything like it -- they won't be mucking about with
the internals of your class. (If they do, they're asking for trouble when you
change something.) That means you can, among other things, override the
behavior of the accessor on subclasses, replace it entirely with a method,
etc.

Just as an example: Suppose you have a class like this:

class Line
  attr_reader :a, :b, :slope
  def initialize(point_a, point_b)
    @a = point_a
    @b = point_b
    @slope = (a.x - b.x) / (a.y - b.y)
  end
end

Now, maybe later on, you notice this isn't working out too well -- maybe not
everyone cares about the slope, so you're wasting cycles calculating it every
time. Maybe the points are changing frequently, and you don't want to have to
re-calculate the slope on every change, only when someone requests it. Since
you defined slope as a reader method, you can just change your implementation:

class Line
  attr_reader :a, :b
  def slope
    (a.x - b.x) / (a.y - b.y)
  end
end

No one has to know that @slope no longer exists.

Granted, you might have some coders who deliberately break things by talking
to @slope directly, but if you've defined an accessor, they have to be a
masochist to want to do it that way. Similarly, because it's just one command
for you to define them, you really have no excuse not to.

I suppose that's the fundamental difference -- in Java and C++, encapsulation
can be enforced to some extent, while in Ruby, it can be easily circumvented.
But Ruby makes it easy to write well-encapsulated code, while Java and C++
make it annoying and tedious.

···

On Saturday 28 November 2009 02:42:08 pm Ralph Shnelvar wrote:

Hi --

> This is the so-called "class instance variable", which is really just
> "an instance variable that happens to belong to a Class object". It's
> common to use the phrase "class instance variable", but it's just a
> way of clarifying what you mean. There's no separate "class instance
> variable" language-level construct.

So ... let's see if I get this.

class X
# "equivalent" to C++'s
# class X {
# protected:
# static sometype at_at_x = 3;
# };
@@x = 3

# "equivalent" to C++'s
# class X {
# private:
# sometype at_x;
# X::X() {at_x =3;}
# };
# at_x is not "inheritable" since it is private.
@x = 3

@x belongs to self. Inside a class definition, self is the class:

   class X
     p self # Output: X
   end

Therefore, if you create an instance variable, it belongs to X (the
class object):

   class X
     @var = 1 # this @var belongs to the class object X (i.e., self)
   end

   p X.instance_variables # Output: ["@var"]

The same thing happens with EVERY object in Ruby. If self is object x,
then @var is an instance variable of object x:

   class C
     def greet
       p self
       @var = 1
       p instance_variables
     end
   end

   C.new.greet

Output:

   #<C:0x484554> (i.e., an instance of class C)
   ["@var"] (the i.vars of that instance)

   str = "I'm a string"
   str.instance_eval do # instance_eval sets "self" for the
     @var = 1 # duration of a code block.
     p self
     p self.instance_variables
   end

Output:

   "I'm a string"
   ["@var"]

I repeat: instance variables are always pegged to "self". They are not
usefully understood as private or public. You can say, informally,
that instance variables are "private", in the sense that they only
appear when self is the object that owns them. But it's kind of
pointless since there's no other state they can be in; there's no such
thing as a "public" instance variable.

# No equivalent notion in C++. It's just a temporary variable
x = 3
end

- - - -

It appears to me that "class" is a jumble of two kinds of very
different semantics.

There is the notion of a class as a template for instances of the
class.

Then there is a very different notion of a sorta static class that
has it's own variables that do not propagate to instances; and may
(@@x) or may not (@x) propagate and be accessile to static subclasses inherited from
the static superclass.

I have to admit that in nine years of using, teaching, and writing
books about Ruby, I don't think I've ever used the word "static" to
describe anything in Ruby. Ruby and "static" don't mix :slight_smile:

A lot to wrap one's head around. I assume that there are good design
reasons to jumble these two concepts together in the semantics of
"class".

I'm a little baffled by why you're trying to understand Ruby by
transliterating concepts and even syntax from C++, and then concluding
that Ruby is a "jumble" because there's no one-to-one correspondence.
I'd really, really urge you to forget about C++ when learning Ruby.
(Easy for me because I don't know C++ in the first place :slight_smile:

In Ruby terms: a class is an object. It has a few special behaviors
that set it apart from other objects, mainly:

   1. it can spawn other objects
   2. it has a keyword dedicated to switching into its "self" scope:
      class

The Class class is a subclass of the Module class. Modules and classes
are storage units for methods (which objects can cause to be executed,
in response to the appropriate methods) and constants.

I would suggest forgetting C++, forgetting class variables, and
playing around with class definitions, the concept of "self", and
instance variables. Try to understand it in Ruby terms. It's actually
much more straightforward that way.

David

···

On Mon, 30 Nov 2009, Ralph Shnelvar wrote:

--
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com
--------------------------------------
My new job: http://tinyurl.com/yfpn9hz

> This is the so-called "class instance variable", which is really just
> "an instance variable that happens to belong to a Class object". It's
> common to use the phrase "class instance variable", but it's just a
> way of clarifying what you mean. There's no separate "class instance
> variable" language-level construct.

So ... let's see if I get this.

Sorry, I don't remember enough C++ to help you here.

It appears to me that "class" is a jumble of two kinds of very
different semantics.

There is the notion of a class as a template for instances of the
class.

Correct.

Then there is a very different notion of a sorta static class that
has it's own variables that do not propagate to instances; and may
(@@x) or may not (@x) propagate and be accessile to static subclasses
inherited from the static superclass.

Well, my advice is to forget that @@x exists at all -- I've never properly
understood how it propagates or how to properly manage it, and it seems to be
an invitation for disaster.

But you're half-right...

A lot to wrap one's head around. I assume that there are good design
reasons to jumble these two concepts together in the semantics of
"class".

It's very simple, really:

In Ruby, EVERYTHING is an object.

You may have seen this cute example before:

class Fixnum
  def + other
    5
  end
end

That's right, ordinary integers are just objects, and arithmetic operators are
just methods, which can be overridden. And if you type the above into IRB, you
can prove that 2+2==5, for very strange definitions of +.

But this is the crucial concept: Numbers are objects. True and false are
objects. Even null is an object -- the object is called nil, and it is an
instance of NilClass. Files are objects. Sockets are objects. Constants are
objects. Symbols are objects.

EVERYTHING is an object. So, EVERYTHING has the semantics of an object. In
addition, everything that's an object is an instance of a class.

Or, to put it another way: The number 5 has the semantics of an ordinary
integer, but also the semantics of an object. You can prove it to yourself:

class Fixnum
  attr_accessor :message
end

That's right, numbers can have methods, even instance variables! Type that
into IRB and try this:

5.message = 'Hello, world!'
4.message
5.message

If you can wrap your head around this concept, it shouldn't surprise you too
much that classes are objects, and modules are objects, too. Classes are
instance of the class "Class", while modules are instances of the class
"Module".

So the idea of "static" is really unnecessary baggage in this discussion. If
you're looking for something similar, I've already presented one option, but
it's not really "static", just like an each loop isn't really a foreach loop.
Here's a complete answer to the question "How many objects of type Foo are
there?" in the traditional C++ style:

class Foo
  class << self
    # These are about the Foo class itself, as an object.
    # Any methods here are methods on the Foo object itself,
    # not instances of Foo:
    def count
      @count ||= 0
    end
    attr_writer :count
    def finalizer
      @finalizer ||= lambda do
        self.count -= 1
      end
    end
  end

  # These are instance methods on the Foo class:
  def initialize
    self.class.count += 1
    ObjectSpace.define_finalizer(self, self.class.finalizer)
  end
end

As you can see, finalizers are kind of cumbersome to use (so don't use them,
you almost certainly don't need them), but they should work. Whenever the
garbage collector finally eats those objects, the count will go down. (You can
force the matter by calling GC.start, but that's for debugging purposes only!)

Now, what's going on here? Probably the most confusing part is this statement:

class << self

What is that doing? That's opening what's called the metaclass of an object.
Every object has a metaclass, which is easiest to think of like this: When you
call Foo.new, you get an object which inherits from a class unique to that
object, which in tern inherits from Foo.

It's actually not quite like that, but that gives you an idea of what's going
on. For example, try this:

a = 'foo'
def a.bar
  5
end

If you understand what that does, then this does the exact same thing:

a = 'foo'
class << a
  def bar
    5
  end
end

Now, what is self inside the Foo class? It's the Foo object itself.

The simplest way to explain what all that code is doing is to remember that I
was just using Foo as an object because it seemed a convenient place to store
values common to all Foos. I could just as easily have done this (for the non-
finalized version):

class Foo
  Count = 0
  def initialize
    Count += 1
  end
end

It'll whine because I'm reassigning constants, but you see the point. I mean,
I could also do this:

FooCount = 0
class Foo
  def initialize
    FooCount += 1
  end
end

It's just that the Foo object is already there, and makes sense for this
purpose.

Also, if you haven't seen this before, don't let it frighten you:

@count ||= 0

That's providing a default value for @count. When you execute that code, it
checks whether @count has a positive value -- if it doesn't, it assigns 0 to
@count. Either way, the (possibly new) value of @count will be returned.

So regarding your musings as to whether there's a good design reason, I'd
argue yes and no. No, it really doesn't seem good design, at first glance,
that numbers can have instance variables, because why would that ever, ever,
be a good idea?

But yes, it actually gives a nice uniform model. Again, EVERYTHING is an
object, so EVERYTHING has methods, instance variables, a metaclass, and so on.

···

On Monday 30 November 2009 01:43:38 am Ralph Shnelvar wrote:

> It won't tell you how many Foo objects actually exist. It's more a
count of DM> how many have ever been created.

Cool.

Is there a way to tell how many instances actually exist? Is there
anything like a destructor for class instances? Just curious.

These are separate questions.

[snip]

I suppose that's the fundamental difference -- in Java and C++, encapsulation
can be enforced to some extent, while in Ruby, it can be easily circumvented.
But Ruby makes it easy to write well-encapsulated code, while Java and C++
make it annoying and tedious.

Oh, wow, what a great explanation! Thanks for taking the time. Wow.

···

On Saturday 28 November 2009 02:42:08 pm Ralph Shnelvar wrote:

Also, if you haven't seen this before, don't let it frighten you:

@count ||= 0

That's providing a default value for @count. When you execute that code, it
checks whether @count has a positive value -- if it doesn't, it assigns 0 to
@count. Either way, the (possibly new) value of @count will be returned.

Does it? I thought this would only give @count the value 0 if it
previously had the value nil or false, and that if the count was -7
that would remain. Did you mean "@count has a true value" instead of
"@count has a positive value"?

irb(main):001:0> @count = -7
=> -7
irb(main):002:0> @count ||= 0
=> -7
irb(main):003:0> @count = nil
=> nil
irb(main):004:0> @count ||= 0
=> 0

C:\Documents and Settings\paul.smith>ruby -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32]

···

--
Paul Smith
http://www.nomadicfun.co.uk

paul@pollyandpaul.co.uk

David Masover:

class Line
  attr_reader :a, :b
  def slope
    (a.x - b.x) / (a.y - b.y)
  end
end

No one has to know that @slope no longer exists.

Granted, you might have some coders who deliberately break things by
talking to @slope directly, but if you've defined an accessor, they
have to be a masochist to want to do it that way. Similarly, because
it's just one command for you to define them, you really have no
excuse not to.

Also, if they’re accessing @slope directly, they deserve punishment
– and I don’t mean ‘deserve’ solely in the bad-for-them sense, but also
in a good-for-them way: it means their code was tailored to work with
version X of your code, and if it relied on such low-level internals,
it’s actually beneficial for them to know outright that your internal
representation changed (and they might want to examine all of the places
in their code that depend on the internal state of your objects).

— Shot

···

--
Clinical psychology seems designed for people too
smart for religion but not smart enough for science.
                   [Paul Lutus, Asperger’s by Proxy]

Whoops, yes, I did. You're right.

···

On Monday 30 November 2009 04:18:06 am Paul Smith wrote:

> Also, if you haven't seen this before, don't let it frighten you:
>
> @count ||= 0
>
> That's providing a default value for @count. When you execute that code,
> it checks whether @count has a positive value -- if it doesn't, it
> assigns 0 to @count. Either way, the (possibly new) value of @count will
> be returned.

Does it? I thought this would only give @count the value 0 if it
previously had the value nil or false, and that if the count was -7
that would remain. Did you mean "@count has a true value" instead of
"@count has a positive value"?