Ruby Zucker 1

What is it?

Zucker is the German word for sugar (pronunciation). This gem adds syntactical sugar in the form of independent, lightweight scripts that make Ruby even more sweet. Read this blog post for a little introduction.

Install

gem install zucker # might need sudo

Usage / Organisation

The gem consists of many small snippets, called cubes, which are bundled in packages. Currently, there are two packages available: default and debug. You can use a package be requiring it in this way: require 'zucker/default' and require 'zucker/debug' Since there aren't any dependencies within the gem, you could also pick only the cubes you want: require 'zucker/egonil'

You can also lock your require to a specific version of Zucker by simply putting the version before the cube name in this way: require 'zucker/1/egonil'. Future releases of the gem will include all previous (main) versions, so the behaviour of these directly required cubes will not change (except for critical bugs).

Cubes

D

Summary Easy debug printing with the p alternative .D. It outputs to stdout and returns self. Accepts a block.
Methods/Usage
Object#D
some.D.methods.D.noone.D.knows.D
# ...outputs 4 lines with the inspected objects
# => (result)

21+Math.sin(42).D
# outputs -0.916521547915634
# => 20.0834784520844

name = 'Earth'
'Hello ' + name.D{|e| "The length is: #{e.size}"}
# outputs "The length is: 5"
# => 'Hello Earth'
Further information This is inspired by the funny .tap method
Specification (show)
require 'D'

describe 'Object#D' do

  let :a do
    [ 1, "1", 2..5, [], {:hallo => :du}, nil, true ]
  end

  it 'should not change the object"s value' do
    a.each{ |e|
      (e.D).should == e
    }
  end

  it "should puts .inspect if no block is given (and not change the object's value)" do
#    a.each{ |e|
#      (e.D).should == e
#    }
  end

  it "should puts the block if it is given (and not change the object's value)" do
    a.each{ |e|
      (e.D{|value| "This is a: #{value}"}).should == e
    }
  end
end
Source (show)
module Kernel
  def D(*args, &block)
    if args.empty?
      tap{
        if block_given?
          puts yield self
        else
          puts self.inspect
        end
      }
    else
      raise ArgumentError, ".D - The parser thought that the code after .D are method arguments... Please don't put a space after D or use .D() or .D{} in this case!"
#      eval ...
    end
  end
end

# J-_-L
Compatibility 1.9, 1.8

aliases

Summary Some convenient aliases (and constants) for existing methods.
Methods/Usage
Object#is_an?
Object.is_a?
Enumerable#with
Enumerable#zip
Enumerable#%
Enumerable#zip
Array#**
Array#product
Hash#+
Hash#merge
Binding#[]
Binding#eval
Infinity
1.0 / 0.0
NaN
0.0 / 0.0
Specification (show)
require 'aliases'

describe '(aliases)' do
  it 'should create these aliases [ sorry, no real spec for this one :P ] ' do
  # alias is_an? is_a?

  #  module Enumerable
  #    alias with zip
  #    alias %    zip
  #  end

  #  class Array
  #    alias ** product
  #  end

  #  class Hash
  #    alias + merge
  #  end

  #  class Binding
  #    #alias [] eval
  #    def [](expr)
  #      self.eval "#{expr}"
  #    end
  #  end

  end

  it 'should define these constants' do
    Infinity.finite?.should == false
    NaN.nan?.should         == true
  end
end
Source (show)
alias is_an? is_a?

module Enumerable
  alias with zip
  alias %    zip
end

class Array
  alias ** product
end

class Hash
  alias + merge
end

class Binding
  #alias [] eval
  def [](expr)
    self.eval "#{expr}"
  end
end

# constants - who would use these in real-world code for other things?
Infinity = 1.0 / 0.0 # or 2*Float::MAX
NaN      = 0.0 / 0.0

# J-_-L
Compatibility 1.9, 1.8

array

Summary Methods one could miss for Array.
Why?

Array has & and |, but why does it not have ^?

sum is an alias for inject(:+), but it is just needed pretty often!

Methods/Usage
Array#^
[1,2,3,4] ^ [3,4,5,6]  # => [1,2,5,6]
Array#sum
[1,2,3,4,5].sum  # => 15
Array#chrs
[72, 97, 108, 108, 111].chrs  # => 'Hallo'
Specification (show)
require 'array'

describe 'Array#^' do
  it 'should do an exclusive or' do
    a = [1,2,3,4]
    b = [3,4,5,6]
    (a^b).should == [1,2,5,6]
  end
end

describe 'Array#sum' do
  it 'should sum the array' do
    [1,2,3,4,5].sum.should   == 15
    %w|More Ruby|.sum.should == 'MoreRuby'
  end
end

describe 'Array#chrs' do
  it 'should convert the array to a string, using each element as ord value for the char' do
    [72, 97, 108, 108, 111].chrs.should == 'Hallo'
  end
end
Source (show)
class Array
  def ^(other) # TODO: more efficient
    (self - other) +
    (other - self)
  end

  def sum # sry, you just need this one too often
    inject :+
  end

  def chrs
    self.pack 'C*'
  end
end

# J-_-L
Compatibility 1.9, 1.8

array2proc

Summary Calls the method named by the first paramenter and passes the other elements as paramaters.
Why? When using Symbol#to_proc, you often wish to pass parameters.
Methods/Usage
Array#to_proc
[1,2,3,4].map( &[:to_s, 2] )  # => ["1", "10", "11", "100"]
Further information Inspired by this article.
More about to_proc.
Specification (show)
require 'array2proc'

describe 'Array#to_proc' do
  it 'should call the method of the first symbol, using the remaining elements as paramaters' do
    [1,2,3,4].map( &[:to_s, 2] ).should == ["1", "10", "11", "100"]
  end
end
Source (show)
class Array
  def to_proc
    Proc.new{ |obj|
      obj.send *self
    }
  end
end

# J-_-L
Compatibility 1.9, 1.8

binding

Summary Adds a verbose Binding#inspect
Why? It gives you information about the current environment
Methods/Usage
Binding#inspect
binding.inspect
Specification (show)
require 'binding'

describe 'Binding#inspect' do
  it 'should output the current environment'
end
Source (show)
class Binding
  def inspect
    put_vars = lambda { |array|
      if array.empty?
        ' - none'
      else
        array.map{|e| " - #{e}: #{ self.eval '#{e}'}"}*"\n"
      end
    }

"#{self.to_s}
local vars
#{ put_vars[ self.eval 'local_variables' ] }
(instance vars)
#{ put_vars[ self.eval 'instance_variables' ] }
self
 - #{self.eval 'self'}
block_given?
 - #{self.eval 'block_given?'}"

  end
end

# J-_-L
Compatibility 1.9, 1.8

blank

Summary Does pretty the same as in ActiveSupport (Every object can be asked if it is blank)
Why? It's too familiar ;)
Methods/Usage
Object#blank?
'an object'.blank? # => false
Further information See ActiveSupport
Specification (show)
require 'blank'

describe 'Object#blank?' do
  it 'should be blank for blank values' do
    blank_values   = [ nil, false, '', '   ', "  \n\t  \r ", [], {}, // ]

    blank_values.each{ |blank|
      blank.blank?.should == true
    }
  end

  it 'should not be blank for non blank values' do
    present_values = [ Object.new, true, 0, 1, 'a', [nil], { nil => nil } ]

    present_values.each{ |present|
      present.blank?.should == false
    }
  end
end
Source (show)
class Object
  def blank?
    if respond_to? :empty? then empty? else !self end
  end

  def present?
    !blank?
  end
end


{ # what to do              # for which classes
  lambda{ true }         => [FalseClass, NilClass],
  lambda{ false }        => [TrueClass, Numeric],
  lambda{ empty? }       => [Array, Hash],
  lambda{ self !~ /\S/ } => [String],
  lambda{ self == //   } => [Regexp],

}.each{ |action, klass_array|
  klass_array.each{ |klass|
    klass.send :define_method, :blank?, &action
  }
}

# J-_-L
Compatibility 1.9, 1.8

class2proc

Summary Creates a new instance of the class.
Methods/Usage
Class#to_proc
[ [1,2],[3,5,6,7,3] ].map(&Set) # => [ Set[1,2], Set[5,6,7,3] ]
Further information Inspired by Ruby Facets.
More about to_proc.
Specification (show)
require 'class2proc'
require 'set'

describe 'Class#to_proc' do
  it 'should create new instances of the class' do
    [ [1,2],[3,5,6,7,3] ].map(&Set).should == [ Set[1,2], Set[5,6,7,3] ]
  end
end
Source (show)
class Class
  def to_proc
    Proc.new do |*args|
      self.new *args
    end
  end
end

# J-_-L
Compatibility 1.9, 1.8

egonil

Summary Creates a block, where nil does not raise NoMethodErrors.
Methods/Usage
egonil, nn
egonil do
  nil.some_methods.that[:do].not.exist
end # => nil

nn(5){ nil.some_methods.that[:do].not.exist }
# => 5
Further information See this post for more information and discussion
Specification (show)
require 'egonil'

describe 'egonil' do
  it 'should not raise nil exceptions in the block' do
    proc do
      egonil{ nil.some_methods.that[:do].not.exist }
    end.should_not raise_exception
  end

  it 'should return the nil_value if given' do
    egonil(9){ nil.some_methods.that[:do].not.exist }.should == 9
  end

  it 'should restore default behaviour after the block' do
    proc do
      egonil{ nil.some_methods.that[:do].not.exist }
    end.should_not raise_exception

    proc do
      nil.a_method
    end.should raise_exception NoMethodError
  end

  it 'raise NoMethodError for non-nil objects' do
    proc do
      egonil{ 5.a_method }
    end.should raise_exception NoMethodError
  end
end
Source (show)
def egonil(nil_value = nil)
  yield
rescue NoMethodError => e
  if e.message =~ /NilClass$/
    nil_value
  else
    raise NoMethodError
  end
end

alias nn egonil

# J-_-L
Compatibility 1.9, 1.8

enumerable

Summary Enumerable extensions.
Methods/Usage
Enumerable#mash
[1,2,3].mash{|e| [e, e.to_s] } # => {1=>'1',2=>'2',3=>'3'}
Further information Inspired by Ruby Facets' mash
Specification (show)
require 'enumerable'

describe 'Enumerable#mash' do
  it 'should "map" a hash' do
    [1,2,3].mash{|e| [e, e.to_s] }.should == {1=>'1',2=>'2',3=>'3',}
  end
end
Source (show)
module Enumerable
  def mash
    ret = {}
    each{ |kv|
      ret.store *( yield(kv)[0,2] )
    }
    ret
  end
end

# J-_-L
Compatibility 1.9, 1.8

hash

Summary Some sugar for dealing with hashs.
Methods/Usage
Hash.zip
Hash.zip [1,2,3], [4,5,6] # => {1 => 4, 2 => 5, 3 => 6}
Hash#<<
{1 => 2} << [3, 4] # => {1 => 2, 3 => 4}
Further information Some of the operators are inspired by Ruby Facets
Specification (show)
require 'hash'

describe 'Hash.zip' do
  it 'should zip together both given enumerables and take them as key=>values for a new hash'
end

describe 'Hash#<<' do
  it 'should append new elements to the hash'
end
Source (show)
class Hash
  def self.zip(keys,values)
    Hash[ *[1,2,3].zip( [4,5,6] ).flatten ]
  end

  def <<(other)
    case
    when other.is_a?(Hash)
      merge! other
    when other.respond_to?(:to_splat)
      merge! Hash[*other]
    else
      raise TypeError, 'can only append other Hashs and Enumerables'
    end
  end
end

# J-_-L
Compatibility 1.9, 1.8

hash2proc

Summary Use a hash to apply procs to specific objects.
Methods/Usage
Hash#to_proc
[1,2,3,4].map(&{
2 => lambda {|e| e + 1000},
4 => :to_s,
}) # => [1, 1002, 3, '4']
Further information More about to_proc.
Specification (show)
require 'hash2proc'

describe 'Hash#to_proc' do
  it 'should run the proc given in the value for a key in the hash' do
    [1,2,3,4].map(&{
      4 => :to_s,
      # 3 => [:to_s, 2]  # "11" =>  if array2proc is used
      2 => lambda {|e| e + 1000}
    }).should == [1, 1002, 3, "4"]
  end
end
Source (show)
class Hash
  def to_proc
    Proc.new{ |obj|
      if self.member? obj
        self[obj].to_proc.call obj
      else
        obj
      end
    }
  end
end

# J-_-L
Compatibility 1.9, 1.8

iterate

Summary Iterate over one or more collections.
Why? It's like .each with two differences: It feels more like a control structure and you can easily iterate over multiple objects.
Methods/Usage
iterate
iterate [1,2], [3,4,5] do |e,f|
  puts "#{e},#{f}"
end
# outputs
#  1,3
#  2,4
#  ,5
Specification (show)
require 'iterate'

describe 'Object#iterate' do
  let :a   do [1, 2, 3]     end
  let :b   do %w|a b c d|   end
  let :res do Hash.new {[]} end

  it 'should behave like Enumerable#each for a single argument' do
    iterate a do |ele|
      res[:iter] << ele
    end

    a.each do |ele|
      res[:each] << ele
    end

    res[:iter].should == res[:each]
  end

  it 'should pass the right params to the block' do
    res = Hash.new {[]} # TODO: why?
    res[:iter_a_b] = [] # ....
    res[:iter_b_a] = [] # ....


    iterate a, b do |e,f|
      res[:iter_a_b] << [e, f]
#      p res[:iter_a_b], e, f
    end

    res[:iter_a_b].should == [
      [1, 'a'],
      [2, 'b'],
      [3, 'c'],
      [nil, 'd'],
    ]

    iterate b, a do |e,f|
      res[:iter_b_a] << [e, f]
    end

    res[:iter_b_a].should == [
      ['a', 1],
      ['b', 2],
      ['c', 3],
      ['d', nil],
    ]

  end

  it 'should return enumerators if no block is applied' do
  end
end
Source (show)
def iterate(*params)
  # params.shift.zip(*params).each{ |*elements| yield *elements }

  first = params.shift
  if params.empty? # single param - like each
    if block_given?
      first.map{|e| yield e }
    else
      first.map
    end
  else
    padded_first = Array.new( [first, *params].max_by(&:size).size ){|i| first[i] } # append nils
    obj = padded_first.zip *params
    if block_given?
      obj.map{|es| yield *es }
    else
      obj.map.to_enum
    end
  end
end

# J-_-L
Compatibility 1.9, 1.8

ivars

Summary This method lets you easily assign lots of instance variables.
Why? Often, you have to write boilerplate code for assigning instance varialbles, for example this one:
def initialize(variable1, variable2)
  @variable1, @variable2 = variable1, variable2
end

Methods/Usage
instance_variables_from, ivars
def a_method(a = 1, b = 2)
  instance_variables_from binding # assigns @a and @b

  params = {:c => 3, :d => 4}
  instance_variables_from params # # assigns @c and @d
end
Specification (show)
require 'ivars'

describe 'instance_variables_from' do
  it 'should tansform the given parameter to instance variables' do
    def a_method(a = 1, b = 2)
      instance_variables_from binding # assigns @a and @b

      params = {:c => 3, :d => 4}
      ivars params # # assigns @c and @d
    end

    a_method
    @a.should == 1
    @b.should == 2
    @c.should == 3
    @d.should == 4

  end
end
Source (show)
def instance_variables_from(obj, *only)
  iter =
  if    obj.is_a? Binding
    obj.eval('local_variables').map{|e| [obj.eval(e), e] }
  elsif obj.is_a? Hash
    obj.map{|k,v| [v,k] }
  else
#  elsif obj.is_a? Enumerable
    obj.each.with_index
  end

  ret = []
  iter.each{ |value, arg|
    arg = arg.to_s
    if only.include?(arg) || only.include?(arg.to_sym) || only.empty?
      arg = '_' + arg  if (48..57).member? arg.unpack('C')[0]  # 1.8+1.9
      ret << ivar = :"@#{arg}"
      self.instance_variable_set ivar, value
    end
  }
  ret
end
alias ivars instance_variables_from

# J-_-L
Compatibility 1.9, 1.8

kernel

Summary Some useful general shortcut methods
Why? Readability
Methods/Usage
activate_warnings!
activate_warnings! # sets $VERBOSE to 1
deactivate_warnings!
deactivate_warnings! # sets $VERBOSE to 0
library?
library? # checks, if the current file is ran directly
ignore_sigint!
ignore_sigint! # blocks CTRL+C
Specification (show)
require 'kernel'

describe 'activate_warnings!' do
  it 'should set $VERBOSE to true' do
    activate_warnings!
    $VERBOSE.should == true
  end
end

describe 'deactivate_warnings!' do
  it 'should set $VERBOSE to false' do
    deactivate_warnings!
    $VERBOSE.should == false
  end
end

describe 'warnings_activated?' do
  it 'should return $VERBOSE' do
    warnings_activated?.should == $VERBOSE
  end
end

describe 'library?' do
  it 'should return false if the file is invoked directly' do
    library?.should == ( __FILE__ != $PROGRAM_NAME )
  end
end

describe 'ignore_sigint!' do
  it 'should catch ctrl+c signals' do
    # ...
  end
end
Source (show)
def activate_warnings!
  $VERBOSE = true
end

def deactivate_warnings!
  $VERBOSE = false
end

def warnings_activated?
  $VERBOSE
end

def library?
  __FILE__ != $PROGRAM_NAME
end

def ignore_sigint! # ctrl+c
   Signal.trap *%w|SIGINT IGNORE|
end
Compatibility 1.9, 1.8

mcopy

Summary Adds Object#mcopy to create a deep copy using Marshal.
Why? Every Ruby book describes, you can do Marshal.load Marshal.dump object to create a deep copy... But who needs this verbose syntax in everyday coding?
Methods/Usage
Object#mcopy
a = %w[hello world]
b = a.mcopy
Specification (show)
require 'mcopy'

describe 'Object#mcopy' do
  it 'create a (deep) copy via marshalling' do
    a = %w[hello world]
    b = a.mcopy
    b.should == a

    b[0][1,1] = ''
    b.should_not == a
  end
end
Source (show)
class Object
  def mcopy
    Marshal.load Marshal.dump self
  end
  # alias copy mcopy
end

# J-_-L
Compatibility 1.9, 1.8

mm

Summary mm displays an ordered public method list.
Why? See some object's methods without those rarely used inherited methods
Methods/Usage
Object#method_list, Object#mm
'test'.mm 2 # outputs the list (2 levels deep)
Further information See this article for more information
Specification (show)
require 'mm'

describe 'Object#method_list' do
  it 'should display an ordered method list'
end
Source (show)
module Kernel
  def method_list(levels = 1)
    if self.is_a? Module
      klass, method_function = self, :public_methods
    else
      klass, method_function = self.class, :public_instance_methods

      eigen = self.singleton_methods
      if !eigen.empty?
        puts :Eigenclass # sorry for not being up to date, I just love the word
        p self.singleton_methods
      end
    end

    levels.times{ |level|
      if cur = klass.ancestors[level]
        p cur                               # put class name
        p cur.send method_function, false   # put methods of the class
      else
        break
      end
    }

    self # or whatever
  end

  alias mm method_list
end

# J-_-L
Compatibility 1.9, 1.8

regexp2proc

Summary Use &/regex/ to match it against strings
Methods/Usage
Regexp#to_proc
%w|just another string array|.map    &/[jy]/  # => ["j", nil, nil, "y"]
%w|just another string array|.select &/[jy]/  # => ["just", "array"]
Further information More about to_proc.
Specification (show)
require 'regexp2proc'

describe 'Regexp#to_proc' do
  it 'should match the regex' do
    %w|just another string array|.map(     &/[jy]/).should == ["j", nil, nil, "y"]
    %w|just another string array|.select(  &/[jy]/).should == ["just", "array"]
  end
end
Source (show)
class Regexp
  def to_proc
    proc do |e|
      e.to_s[self]
    end
  end
end

# J-_-L
Compatibility 1.9, 1.8

sandbox

Summary Creates a sandbox area.
Why? Ruby comes with sandboxes, but they are hidden (--> integrated) in the $SAFE concept
Methods/Usage
sandbox
sandbox do
  # dangerous commands throw SecurityErrors ($SAFE=4)
end
# everything's normal again
Specification (show)
require 'sandbox'

describe 'sandbox' do
  it 'should throw a SecurityError if bad commands are issued'
  it 'should run the lambda passed as first parameter for errors, if it is given'
end
Source (show)
def sandbox(rescueblock=nil)
  Thread.start do
    $SAFE = 4
    yield
  end.value
rescue SecurityError => e
  if rescueblock
    rescueblock.call e
  else
    raise e
  end
end

# J-_-L
Compatibility 1.9, 1.8

square_brackets_for

Summary This helper methods defines [] and []= for accesing an instance variable.
Methods/Usage
square_brackets_for
class Klass
  def initialize
    @var = {
      :a_key => 1,
      :another_one => 2,
    }
  end

  square_brackets_for :var # creates [] and []=
  # square_brackets_for :var, false # would create only []
end

a = Klass.new
a[:a_key] # => 1
Specification (show)
require 'square_brackets_for'

describe 'square_brackets_for' do

  before do
    class Klass
      def initialize
        @var = {
          :a_key => 1,
          :another_one => 2,
        }
      end

      @eigenvar = {
        :a_key => 99
      }
    end
  end

  it 'should define a [] getter (not a setter) for an instance var, if the second parameter is false' do

    class Klass
      square_brackets_for :var, nil
    end

    a = Klass.new
    a[:a_key].should == 1

    proc do
      a[:this_is] = 'not possible'
    end.should raise_exception NoMethodError
  end

  it 'should define [] and []= for accessing an instance variable' do

    class Klass
      square_brackets_for :var
    end

    a = Klass.new
    a[:a_key].should == 1

    a[:this_is] = 'useful'
    a[:this_is].should == 'useful'
  end

  it 'should also work for class-instance variables' do

    class Klass
      class << Klass
        square_brackets_for :eigenvar
      end
    end

    Klass[:a_key].should == 99
  end

end
Source (show)
def square_brackets_for(ivar, assignment = true)
#  undef []   if respond_to? :[]
#  undef []=  if respond_to? :[]=

#instance_eval do
  define_method :[] do |key|
    (instance_variable_get :"@#{ivar}")[key]
  end

  if assignment
    define_method :[]= do |key, value|
      (instance_variable_get :"@#{ivar}")[key] = value
    end
  end
#end

end

# J-_-L
Compatibility 1.9, 1.8

string

Summary String extensions.
Why? Strings cannot be comfortable enough ;)
Methods/Usage
String#^
'Yes vs No'^3 # => 'Yes'
String#lchomp
'   Yes'.lchomp  # => 'Yes'
String#lchomp!
# mutable lchomp version
String#ords
'Hallo'.ords # => [72, 97, 108, 108, 111]
Specification (show)
require 'string'

describe 'String#^' do
  it 'should give C-like substring access to strings' do
    string = 'Theoretische Informatik ist voll geil!'

    (string|0).should  == 'Theoretische Informatik ist voll geil!'
    (string|1).should  == 'heoretische Informatik ist voll geil!'
    (string|13).should == 'Informatik ist voll geil!'
    (string|-1).should == 'Theoretische Informatik ist voll geil'
    (string|38).should == ''
    (string|99).should == nil
  end
end

describe 'String#lchomp' do
  it 'should chomp on the left side' do
    string = 'Theoretische Informatik ist voll geil!'
    string.lchomp('T').should  == 'heoretische Informatik ist voll geil!'
  end
end

describe 'String#ords' do
  it 'should unpack characters' do
    string = 'Theoretische Informatik ist voll geil!'
    string.ords.should  == [84, 104, 101, 111, 114, 101, 116, 105, 115, 99, 104, 101, 32, 73, 110, 102, 111, 114, 109, 97, 116, 105, 107, 32, 105, 115, 116, 32, 118, 111, 108, 108, 32, 103, 101, 105, 108, 33]
  end
end
Source (show)
class String
  def ^(pos)
    pos = pos.to_i
    if pos >= 0
      self[pos..-1]
    else
      self[0...pos]
    end
  end

  def lchomp(arg=$/)
    self.reverse.chomp(arg).reverse
  end

  def lchomp!(arg=$/)
    self.reverse.chomp!(arg).reverse
  end

  def ords
    self.unpack 'C*'
  end
end

# J-_-L
Compatibility 1.9, 1.8

unary

Summary Easy conversion between strings and symbols.
Why? Sometimes, you do not care if you get a String or Symbol as input - but when analysing it, you often need to choose one format. A concise possibility for this conversion is using the unary operators String#-@ and Symbol#+@
Methods/Usage
String#+@
+'was_string' # => 'was_string'
String#-@
-'was_string' # => :was_string
Symbol#+@
+:was_symbol  # => 'was_symbol'
Symbol#-@
-:was_symbol  # => :was_symbol
Further information Inspired by (I've seen the unary + for Symbol somewhere on the net... but cannot remember where...)
Specification (show)
require 'unary'

describe Symbol, '#+@' do
  it 'should convert to_s' do
    +(:matz) == 'matz' # () 1.8 bug
  end
end

describe Symbol, '#-@' do
  it 'should do nothing' do
    -:matz == :matz
  end
end

describe String, '#+@' do
  it 'should do nothing' do
    +'matz' == 'matz'
  end
end

describe String, '#-@' do
  it 'should convert to_sym' do
    -'matz' == :matz
  end
end
Source (show)
class String
  def +@
    self
  end

  def -@
    to_sym
  end
end

class Symbol
  def +@
    to_s
  end

  def -@
    self
  end
end

# J-_-L
Compatibility 1.9, 1.8 (+:literal not possible)

union

Summary Easy creation of Regexp.unions
Methods/Usage
Regexp#|, String#|
/Ruby\d/ | /test/i | "cheat"
# creates a Regexp similar to:
# /(Ruby\d|[tT][eE][sS][tT]|cheat)/
Specification (show)
require 'union'

describe 'Regexp#|' do
  it 'should create an Regexp.union of both operands' do
    (/hallo/ | /\d+/ | /./).should ==
      Regexp.union( Regexp.union(/hallo/, /\d+/), /./ )
  end
end

describe 'String#|' do
  it_should_behave_like 'Regexp#|'
end
Source (show)
class Regexp
  def |(arg)
    Regexp.union self, arg.is_a?(Regexp) ? arg : arg.to_s
  end
end

class String
  def |(arg)
    Regexp.union self, arg.is_a?(Regexp) ? arg : arg.to_s
  end
end

# J-_-L
Compatibility 1.9