Previous Table of Contents Next


4.7.1. Protocols for Common Objects

The <Object> protocol specifies the messages that all Smalltalk objects support. The majority of messages in this protocol relate to comparing and testing objects. There are also messages for message sends with computed selectors and for producing textual descriptions of objects:

Protocol <Object>
Messages:
== <Object> ^ <boolean> Tests for object identity
~~ <Object> ^ <boolean> Negated test for object identity
= <Object> ^ <boolean> Tests equality
~= <Object> ^ <boolean> Negated test for equality
class ^ <classDescription> Gets an object’s class object
copy ^ <Object> Creates a copy of an object
error: <string> Signals that an error condition has been detected
hash ^ <integer> Gets an object’s equality hash code
identityHash ^ <integer> Gets an object’s identity hash code
isKindOf: <classDescription> ^<boolean> Tests if within a class hierarchy
isMemberOf: <classDescription> ^ <boolean> Tests whether an instance is of a particular class
isNil ^ <boolean> Tests for nil
notNil ^ <boolean> Performs a negated test for nil
perform: <selector> Indicates a unary message send with computed selector
perform: <selector> with: <Object> Indicates message send with computed selector
perform: <selector> with: <Object> with: <Object> Indicates message send with computed selector
perform: <selector> withArguments: <Array> Indicates message send with computed selector
printOn: <writeStream> Writes textual description of an object to a stream
printString ^ <string> Gets a textual description of an object
respondsTo: <selector> ^ <boolean> Tests whether receiver’s behavior includes a selector
yourself ^ <Object> Indicates no-op, return the receiver

Identity is one of the fundamental traits of Smalltalk objects. Identity means that any two distinct objects can be distinguished from each other. The == message is used to test for object identity. == returns true if and only if its receiver and argument are the same object. The message ~~ is the logical negation of ==. The messages isNil and notNil are short-hand tests for identity with the object nil:

  a := Object new.
  b := a.
  a == b “test two references to the same object”
      true
  Object new == Object new “two new objects must be   distinct”
      false
  a isNil   “a was a newly created object”
      false
  b := nil.
  b notNil
      false

In addition to testing for identity, two objects can also be tested for equality using the messages = and ~=. Equality is a much more elusive concept than identity. In general, two objects are considered equal if they may be used interchangeably in most contexts. For example, it seems reasonable to consider two numeric objects that have the same mathematical value to be equal or two strings containing identical character sequences to be equal. For other classes, it is less obvious what should constitute a definition of equality. The default definition of equality implemented by class Object is to define equality the same as identity. Two objects are equal if they are the same object. Many classes refine this definition to provide more specific and useful meanings:

  (3+4) = (3.0+4.0)
      true
  Object new ~= Object new
      true

Hash tables are frequently used in the creation of Smalltalk data structures. The messages hash and identityHash both return integer values that can be used to index hash tables. If a hash table uses object identity (==) to distinguish elements, then identityHash is used as the hash function when indexing the table. If a hash table uses equality (=) to distinguish elements then hash is used as the hash function. Any two object that compare equal using the = message must return equal values for the hash message.

The message copy is used to create a new object that shares most essential characteristics with the receiver of the copied object. Like equality, the exact semantics of copying an object should be defined by each class. The default implementation that is inherited from class Object is to create a new object whose encapsulated state is the same as the receiver’s.

The message class when sent to an instance of a class returns the class object for that class. Here’s an example:

  c := Customer new.
  c class
      Customer

The isMemberOf: message is used to determine if its receiver is an instance of a specific class. The isKindOf: message determines if its receiver is an instance of the argument class or an instance of any of the subclasses of the argument class. The message respondsTo: is used to determine if a message with the argument selector is included in the receiver’s behavior:

  c isMemberOf: Customer
      true
  c isMemberOf: Object
      false
  c isKindOf: Object “Customer is a subclass of Object”
      true
  c respondsTo: #respondsTo:
      true
  ‘abc’ respondsTo: #customerNumber
      false

The message printString is used to produce a string that contains a textual description of its receiver. The exact contents of the string is determined by the class of the receiver and some classes may provide elaborate descriptions of their instances. The description of an object, such as a number, that has a literal representation is the literal. The default description of other objects is to state that it is an instance of its class name. The message printOn: produces the same description as printString, but the description is appended to the <writableStram> argument:

  Customer new printString
      ‘a Customer’
  (3+4) printString
      ‘7’


Previous Table of Contents Next