Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Ruby Programming
Previous Page Home Next Page

Assignment

Just about every example we've given so far in this book has featured assignment. Perhaps it's about time we said something about it.

An assignment statement sets the variable or attribute on its left side (the lvalue) to refer to the value on the right (the rvalue). It then returns that value as the result of the assignment expression. This means that you can chain assignments and that you can perform assignments in some unexpected places.

a = b = 1 + 2 + 3
a 6
b 6
a = (b = 1 + 2) + 3
a 6
b 3
File.open(name = gets.chomp)

There are two basic forms of assignment in Ruby. The first assigns an object reference to a variable or constant. This form of assignment is hard-wired into the language.

instrument = "piano"
MIDDLE_A   = 440

The second form of assignment involves having an object attribute or element reference on the left-hand side.

aSong.duration    = 234
instrument["ano"] = "ccolo"

These forms are special, because they are implemented by calling methods in the lvalues, which means you can override them.

We've already seen how to define a writable object attribute. Simply define a method name ending in an equals sign. This method receives as its parameter the assignment's rvalue.

class Song
  def duration=(newDuration)
    @duration = newDuration
  end
end

There is no reason that these attribute setting methods must correspond with internal instance variables, or that there has to be an attribute reader for every attribute writer (or vice versa).

class Amplifier
  def volume=(newVolume)
    self.leftChannel = self.rightChannel = newVolume
  end
  # ...
end

Sidebar: Using Accessors Within a Class

Why did we write self.leftChannel in the example on page 74? Well, there's a hidden gotcha with writable attributes. Normally, methods within a class can invoke other methods in the same class and its superclasses in functional form (that is, with an implicit receiver of self). However, this doesn't work with attribute writers. Ruby sees the assignment and decides that the name on the left must be a local variable, not a method call to an attribute writer.
class BrokenAmplifier
  attr_accessor :leftChannel, :rightChannel
  def volume=(vol)
    leftChannel = self.rightChannel = vol
  end
end
ba = BrokenAmplifier.new
ba.leftChannel = ba.rightChannel = 99
ba.volume = 5
ba.leftChannel 99
ba.rightChannel 5

We forgot to put ``self.'' in front of the assignment to leftChannel, so Ruby stored the new value in a local variable of method volume=; the object's attribute never got updated. This can be a tricky bug to track down.

Ruby Programming
Previous Page Home Next Page

 
 
  Published under the terms of the Open Publication License Design by Interspire