I have just released Threequals, which provides a Ruby-like #=== operator for Visualworks Smalltalk.

The #=== operator, or “case equals” as it is known, is used in Ruby case statments and gives Ruby a lot of power in flexibly matching objects.

Smalltalk doesn’t have (or need) a case statement, but this kind of flexible matching can be useful in other situations. For example, I now use #=== to match expected arguments in my DoubleAgents library.

In this implementation, two objects are === if they are =. In addition:

  • A BlockClosure is === to an object if the block evaluates to true when passed that object.

  • A Class is === to an object if the object is an instance of the class or one of its subclasses.

  • An Interval is === to a number if that number is within the endpoints of the interval, including the endpoints.

  • If the optional Threequals-Regex package is loaded, a regular expression (RxMatcher) is === to a string if the string matches the regex.

Be aware that === is asymmetric. The object that has specialized #=== must be the receiver of the message. That is, (1 to: 5) === 4 answers true, but 4 === (1 to: 5) answers false.

This seems like an arbitrary restriction, but consider the following:

Asymmetric Example
BlockClosure === [:x | x isBehavior not]
[:x | x isBehavior not] === BlockClosure

Should this evaluate to true or false?

Threequals’ primary home is the Cincom Public Store Repository. Check there for the latest version. I’ve also put a snapshot of the current version of Threequals on GitHub. The Readme file on GitHub includes documentation of the API of Threequals if you’d like more information before diving in. I will also be submitting it for inclusion as a contributed package in a forthcoming Visualworks release.

Threequals was developed in VW 7.9.1, but is intended to be compatible with VW 7.7 and later.

Threequals is licensed under the MIT license.