<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Talk Like A Duck: Tag objectidentity</title>
    <link>http://talklikeaduck.denhaven2.com/articles/tag/objectidentity</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In Ruby, it's not the dog, it's the tricks!</description>
    <item>
      <title>On Variables, Values, and Objects</title>
      <description>&lt;p&gt;I&amp;#8217;ve recently observed some posts to ruby-talk which evidence some confusion on the part of the posters about the relationship between variables and objects in Ruby.  One currently active thread concerns several participants who are upset that instances of the Matrix class in the Ruby standard library can&amp;#8217;t be changed once created.&lt;/p&gt;


	&lt;p&gt;In Ruby, like in other uniformly object-oriented languages, the relationship between variables and their values is subtly different than in other languages, and this is a crucial paradigm shift, which must be crossed in order to understand Ruby.&lt;/p&gt;


	&lt;p&gt;In many languages a variable names an area in memory which holds a &amp;#8220;bag-of-bits&amp;#8221; representing the value of the variable.  The size of that area depends on the type of the variable.  A variable holding an integer might be 4-bytes long, while one holding a particular structure might be 325 (or whatever) bytes.&lt;/p&gt;


	&lt;p&gt;In a uniformly object-oriented language, &lt;strong&gt;all&lt;/strong&gt; variables reference objects, and &lt;strong&gt;any&lt;/strong&gt; variable can reference &lt;strong&gt;any&lt;/strong&gt; object, or different objects over time.  My good friend at &lt;span class="caps"&gt;IBM&lt;/span&gt;, the late David N. Smith, used to say that in such a language, &amp;#8220;all variables are the same size,&amp;#8221; when he wrote about or taught Smalltalk.&lt;/p&gt;


	&lt;p&gt;This distinction can trip up the unwary.  Let&amp;#8217;s try to clear some of the stumbling blocks out of the way.&lt;/p&gt;


&lt;h2&gt;Ruby Variables Don&amp;#8217;t Have (Permanent) Classes&lt;/h2&gt;
In one recent thread, someone suggested adding a method to the &amp;#8220;class of a variable.&amp;#8221; 

The problem with this idea, is that a variable doesn&amp;#8217;t really have &lt;strong&gt;a&lt;/strong&gt; class.  For example, consider thiscode:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;require 'matrix'
   a = 5
   a = a * 1.0
   a = a * Matrix.identity(3)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Here the variable a refers to a sequence of objects, each with a different class.  First a Fixnum, then a Float, then a Matrix.  While Fixnum, and Float inherit from Numeric, Matrix doesn&amp;#8217;t but it can form a duck-type with Numeric in many uses.&lt;/p&gt;


This also illustrates that &amp;#8220;all variables are the same size.&amp;#8221;  In a language like C, a variable holding an integer, will probably have a diffferent size as one holding a double (which is what Ruby defines as the representation of a float), and one which holds a 3&amp;#215;3 matrix of doubles certainly will be bigger than one holding a scalar double.
&lt;h2&gt;Ruby Variables Hold Object References, not Object State&lt;/h2&gt;
The magic which allows this is the fact that in Ruby, as in  Smalltalk, a variable doesn&amp;#8217;t hold the &amp;#8220;bag-of-bits&amp;#8221; which represents a particular data-structure. Instead it contains a reference to an object which holds the &amp;#8220;bag-of-bits.&amp;#8221;  The actual structure of that &amp;#8220;bag-of-bits&amp;#8221; is of no concern to, and is hidden from the variable and it&amp;#8217;s users.

	&lt;p&gt;This encapsulation barrier is key to what makes a language truly &amp;#8220;object-oriented,&amp;#8221; at least the way I use the term.&lt;/p&gt;


	&lt;p&gt;The &amp;#8220;bag-of-bits&amp;#8221; which represents a particular object &lt;strong&gt;is&lt;/strong&gt; visible to the methods of that object&amp;#8217;s class, at least in an abstract way. Some details are even hidden to those methods at the Ruby source code level, and are tied up in the language implementation, hand written extensions to Ruby usually do need to deal with those details.&lt;/p&gt;


	&lt;p&gt;In Smalltalk, the pseudo-variable &lt;i&gt;self&lt;/i&gt; is actually strongly typed in the C-sense since instances of Smalltalk classes have a fixed structure, and &lt;i&gt;self&lt;/i&gt; in a method is guaranteed to refer to an instance of the class owning the method or one of it&amp;#8217;s subclasses, and instance variables are found in known slots within the object.&lt;/p&gt;


	&lt;p&gt;In Ruby it&amp;#8217;s a little different because Ruby instance variables are created dynamically and accessed via a hash table within the object, at least in the 1.8.x implementation.&lt;/p&gt;


	&lt;p&gt;As a first approximation, we can initially think of variables as holding pointers to objects, but I&amp;#8217;ll expose this for the pedagogical lie that it is, a little later in this article.&lt;/p&gt;


&lt;h2&gt;Mutability, and Aliasing&lt;/h2&gt;
Here&amp;#8217;s one of those stumbling blocks for those who expect variables in a uniformly object-oriented language to work like they do in a language like C or Fortran:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt; 1: a = [1, 2, 3]
 2: b = [1, 2, 3]
 3: c = a

 4: a[1] = 0

 5: p a #=&amp;gt; [1, 0, 3]
 6: p b #=&amp;gt; [1, 2, 3]
 7: p c #=&amp;gt; [1, 0, 3]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Everything looks pretty normal up ot line 7. We never did anything with &lt;i&gt;c&lt;/i&gt; after we assigned it a value, but it  doesn&amp;#8217;t seem to have held it&amp;#8217;s value.&lt;/p&gt;


	&lt;p&gt;Or has it?&lt;/p&gt;


	&lt;p&gt;Well, it actually has, since it&amp;#8217;s value is a reference to an object, and that &lt;strong&gt;object&lt;/strong&gt; is the same one referenced by a.&lt;/p&gt;


Line 4 might &lt;i&gt;look&lt;/i&gt; like an assignment to the variable &lt;i&gt;a&lt;/i&gt;, but it&amp;#8217;s really a method call to the array which a happens to be referencing at the time.  And that method (called []=) changes, or &lt;i&gt;mutates&lt;/i&gt; that array.  That change will be visible through the variables &lt;i&gt;a&lt;/i&gt;, &lt;i&gt;c&lt;/i&gt; and any others that reference that particular array.  Multiple references to the same object are called aliases to that object.  They might be named variables, or referenced which are inside another object:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt; 8: d = [[1, 2, 3], [4, 5, 6]]
 9: e = d
10: d[1][1] = &amp;quot;Fred&amp;quot;
11: p e #=&amp;gt; [[1, 2, 3], [4, &amp;quot;Fred&amp;quot;, 5]]]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;While such mutating methods are often very useful, this effect of aliasing is something which the Ruby programmer who uses them needs to keep in mind.&lt;/p&gt;


	&lt;p&gt;Many built-in Ruby classes have both mutating, and non-mutating versions of methods, for example Array#compact returns a new array which is a copy of the receiver with nil elements removed, leaving the original array intact, while Array#compact! mutates the receiver and removes the nil&amp;#8217;s in-place.&lt;/p&gt;


	&lt;p&gt;As with &lt;i&gt;compact&lt;/i&gt; and &lt;i&gt;ocmpact!&lt;/i&gt;, it&amp;#8217;s standard practice to give such mutating methods a name with a trailing &amp;#8216;&lt;strong&gt;!&lt;/strong&gt;&amp;#8217; which serves as a warning that they mutate the receiver.  It&amp;#8217;s a warning to the wise.&lt;/p&gt;


&lt;h2&gt;That Little White/Pedagogical Lie, or Variables and Object Identity&lt;/h2&gt;
I said above that thinking that variables hold pointers to objects was a first approximation to reality.  The fact is they really don&amp;#8217;t

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;12: a1 = [1, 2, 3]
13: a2 = [1, 2, 3]
14: p a1.object_id #=&amp;gt; -605450882
15: p a2.object_id #=&amp;gt; -605225658&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The object_id method returns a number which is unique in the sense that no two active objects will ever have the same object_id, and a given object will always have the same object_id.  In the Ruby 1.8.x implementation, object_id actually just gives the bits of the value used to reference the object in the guise of a Fixnum.&lt;/p&gt;


So we see here that a1 and a2 are diffferent objects.  Let&amp;#8217;s try a few more objects:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;14: i1 = 1
15: i2 = 1
16: p i1.object_id #=&amp;gt; 3
17: p i2.object_id #=&amp;gt; 3
18: sym1 = :sym
19: sym2 = :sym
20: p sym1.object_id #=&amp;gt; 4090126
21: p sym2.object_id #=&amp;gt; 4090126 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Here&amp;#8217;s another surprise.  Before when we created two different arrays, we ended up with two different objects. But even though we never assigned i2 to i1, or sym2 to sym1, the &amp;#8216;two&amp;#8217; 1s have the same object_id, and the &amp;#8216;two&amp;#8217; symbols named :sym share an object_id, what&amp;#8217;s that about?&lt;/p&gt;


	&lt;p&gt;Certain classes ensure that if &amp;#8216;two&amp;#8217; of their instances are equal they are the same object.  We can see that Fixnum, and Symbol do this, others are NilClass, TrueClass, and FalseClass.  For symbols, this conflation of value and identity is part of their definition, for the others, it&amp;#8217;s probably not strictly necessary, but it makes some common operations like testing for equality, and in the case of Fixnums arithmetic operations, much faster.&lt;/p&gt;


What&amp;#8217;s really held in variables is a value which can either be used to recognize that the object is one of these special objects, or that can be mapped efficiently to the real address of the object. The details are implementation-specific, and not really germane to the current topic, so I won&amp;#8217;t go into them in this article.
&lt;h2&gt;Immutable Objects&lt;/h2&gt;
It&amp;#8217;s often advisable to design classes without mutating methods.  For example, Fixnum has a method [] which returns the &lt;i&gt;n&lt;/i&gt;th bit of the representation of the number where bit 0 is the least significant bit. Suppose that it also had a method []=, which &lt;strong&gt;set&lt;/strong&gt; the value of the cooresponding bit:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#Hypothetical code - with a tribute to Jimi Hendrix
h1: a = 6
h2: b = 6
h3: a[0] = 1; a[1] = 0; a[2] = 0; a[3] = 1
h3: p a #=&amp;gt; 9
h4: p b #=&amp;gt; 9&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Since all 6&amp;#8217;s are the same object, then if Fixnum had mutating methods, we could make all 6&amp;#8217;s turn out to be 9.  While Jimi might not mind, my program might not like it.&lt;/p&gt;


	&lt;p&gt;And it would cause head-scratching debugging sessions.  Thirty-two years ago, I found myself in just such a situation. Fortran II had a bug in the language specification which allowed the value of  integer literals to be changed when you passed a literal as an argument to a subroutine which assigned to that argument.  I spent over a day trying to figure out why my program didn&amp;#8217;t work.&lt;/p&gt;


	&lt;p&gt;For this reason, to quote Martha Stewart, it&amp;#8217;s a good thing that the Ruby numeric classes don&amp;#8217;t have mutating methods.  Even though Bignums and Floats don&amp;#8217;t conflate value with identity, it would probably be even more mystifying to find that some instance of 1.5 changed to 1.45 when other&amp;#8217;s didn&amp;#8217;t. To me it seems far better to head off that particular &amp;#8216;feature&amp;#8217; at the pass.&lt;/p&gt;


	&lt;p&gt;Another reason for this choice of immutability is taken from functional programming.  Although Ruby is not really an FP language, it takes many concepts from that paradigm. In FP, functions with side-effects are disallowed, and mutation is certainly a side-effect.  Taking FP to the limit makes doing things which require side-effects, like I/O, take special tricks.  Ruby allows side-effects, and doesn&amp;#8217;t &lt;strong&gt;require&lt;/strong&gt; an FP approach, but like other features like regular expressions, understanding functional approaches is a useful tool in the Ruby programmer&amp;#8217;s bag.&lt;/p&gt;


&lt;h2&gt;Immutability at the Instance Level&lt;/h2&gt;
Ruby Object&amp;#8217;s have a freeze method which makes a particular instance immutable:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;F1: a1 = [1, 2, 3]
F2: a2 = a1
F3: a1.freeze
F4: a1[1] = &amp;quot;Fred&amp;quot; #=&amp;gt; TypeError: can't modify frozen array
F5: a2[1] = &amp;quot;Fred&amp;quot; #=&amp;gt; TypeError: can't modify frozen array&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Beware, though, that this only freezes the object itself and not it&amp;#8217;s sub-objects, or referenced objects:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;F6: a3 = [[1, 2, 3], [4, 5, 6]]
F7: a3.freeze
F8: a3[0][1] = &amp;quot;Fred&amp;quot;
F9: p a3 #=&amp;gt; [[1, &amp;quot;Fred&amp;quot;, 3], [4, 5, 6]]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Matrix and Mutability&lt;/h2&gt;
Following the pattern established by Numerics, the designer of the Matrix class, who, according to the comments in the source code, ported it from Smalltalk, made Matrix instances immutable.

	&lt;p&gt;This upsets some who prefer to think of a Matrix as a 2-dimensional array rather than a mathematical construct which acts much like a numeric in linear algebra.&lt;/p&gt;


	&lt;p&gt;If you want to view matrices that way you&amp;#8217;ve got a few choices:&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;Swim-against the current: Monkey-patch Matrix to add mutating methods.&lt;/li&gt;
&lt;li&gt;Swim with the current: Use the Matrix#to_a and Matrix[] to get a mutable array and then create a new Matrix from it:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;M1: m1 = Matrix.identity(3)
M2: p.m1 #=&amp;gt; Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
M3: a1 = m1.to_a
M4  a1[1][1] = 3
M4  m1 = Matrix[a1]
M5: p m1 #=&amp;gt; Matrix[[[1, 0, 0], [0, 3, 0], [0, 0, 1]]]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Find a new stream: look at other sources of a mutable 2-dimensional array, for example &lt;a href="http://narray.rubyforge.org/"NArray&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
The choice, gentle reader, is yours.  I hope that my efforts help you make it a more informed choice.</description>
      <pubDate>Wed, 13 Sep 2006 15:47:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:c2c1aa30-0c31-4708-8f00-3e7bd05be738</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2006/09/13/on-variables-values-and-objects</link>
      <category>ruby</category>
      <category>smalltalk</category>
      <category>nubies</category>
      <category>variables</category>
      <category>objects</category>
      <category>objectidentity</category>
      <category>semantics</category>
      <category>implementation</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/29</trackback:ping>
    </item>
  </channel>
</rss>
