Operating Nothing

There is an operator in Ruby, that does nothing: The unary plus operator. It is part of the language for keeping symmetry with the unary minus operator!

This is awesome, an operator for free! How can we utilize it?

Update: In Ruby 2.3, the plus operator got its first purpose: Create an unfrozen copy of a string

string = "frozen string".freeze
string.object_id # => 19066860
string.frozen? # => true

copy = +string
copy.object_id # => 19012140
copy.frozen? # => false

1 | Logging

require 'logger'

# Definition
$logger = Logger.new(STDOUT)

class Object
  def +@
    $logger.warn(self.inspect)
  end
end

# Usage
+/Ruby/
# => W, [2015-05-28T10:52:51.115334 #16630]  WARN -- : /Ruby/

We could use it for logging. But this is more of the category nice, but feels like there is no real reason for the syntactic sugar.

2 | Null Objects

A more useful case would be to simplify often done object conversions, for example, converting null objects to actual nil for comparsions:

# Definition
class Object
  def +@
    null? ? nil : self
  end

  def null?
    false
  end
end

class NilClass
  def null?
    true
  end
end

# Usage
class CustomNullObject
  def null?
    true
  end
end

null = CustomNullObject.new

+nil #=> nil
+null #=> nil
+"Ruby" #=> "Ruby"

See null_question and null_plus for a gemified version of the code above.

3 | Symbol Conversion

Another conversion related use of +@ is the following snippet, which also defines -@. It will convert String and Symbol into each other's representation. It can be used as some kind of alternative to libraries that provide HashWithIndifferentAccess-kind functionality, by always explicitely converting the key:

# Definition
class String
  def +@
    self
  end

  def -@
    to_sym
  end
end

class Symbol
  def +@
    to_s
  end

  def -@
    self
  end
end

# Usage
hash   = { key: "value" }
symbol = :key
string = "key"

hash[-symbol] # => "value"
hash[-string] # => "value"

By the way, this would not be needed, if we make symbols frozen strings!

4 | Test Rocket!

Thinking further: How to get most of out operators? How about a testing framework:

require 'testrocket'

# BASIC USAGE
# +-> { block that should succeed }
# --> { block that should fail }

+-> { Die.new(2) }
--> { raise }
+-> { 2 + 2 == 4 }

# These two tests will deliberately fail
+-> { raise }
--> { true }

# A 'pending' test
~-> { "this is a pending test" }

# A description
!-> { "use this for descriptive output and to separate your test parts" }

See peterc/testrocket for further info!

5 | Superators!

There was a library that carried operator magic to the extremes: It let you define superators, which are new binary operators that use a chain of unary operators as their name! This is what it looked like:

# Definition
class Array
  superator "<---" do |operand|
    if operand.kind_of? Array
      self + operand.map { |x| x.inspect }
    else
      operand.inspect
    end
  end
end

# Usage
[1,2,3] <--- [4,5,6]

The library is not maintained, anymore, but it is the craziest leveraging of Ruby's capabalities I've ever seen! The repo is at jicksta/superators.

More Idiosyncratic Ruby