Freighthopper

Some monkeypatches for riding the Rails

Eigenclass & define_eigenmethod

Quick access to the eigenclass.

class Example
  def private?() false end
end

e = Example.new
e.define_eigenmethod(:private?) {true}
e.private? #=> true
e.eigenclass #=> #<Class:#<Example:0x18b684c>>
e.eigenclass.instance_methods.include? :private? #=> true
e.eigenmethod :private? #=> #<UnboundMethod: Example#private?>

Example.new.private? #=> false

Antonym Accessor

Antonym accessor provides some simple ruby sugar for defining inverse relationships, like between private and public, enabled and disabled, on and off, etc. I found myself defining these often enough I figured I’d extract the functionality.

class Example
  def private?() @private end
  def private=(p) @private = p end
  antonym_accessor :private => :public
end

e = Example.new
e.private = true
e.public? #=> false
e.public = true
e.private? #=> false

Define and alias

The alias_method_chain pattern requires you to def the method and then separately alias_method_chain it. This pattern is not as dry as it could be. Hence, define_and_alias.


# What would previously have been:
def foo_with_something(arg)
  foo_without_something arg
  5.times {puts arg}
end
alias_method_chain :foo, :something

# Becomes:
define_and_alias :foo, :something do |arg|
  foo_without_something arg
  5.times {puts arg}
end

One less line, and more dry.

Eval with options

This is a slight tweak to with_options. Here’s the transformation in code:

# What was:
map.with_options :name => 'freighthopper' do |fh|
  fh.something
  fh.that
end

# Becomes

map.eval_with_options :name => 'freighthopper' do
  something
  that
end

Is one of

# What was
if object.is_a?(Foo) || object.is_a?(Bar) || object.is_a?(Bibble)
  ...
end

#or maybe it was

case object
when Foo, Bar, Bibble
  ...
end

#becomes
if object.is_one_of? Foo, Bar, Bibble
  ...
end

Lazy alias

# What was:
def to_s() name end
#this is not the same as alias_method, because if #name
#is defined through method missing / lazily, it won't
#work.  Lazy alias is like alias_method, lazy-style

lazy_alias :to_s, :name

Or if blank

There are lots of implementations of this, but this is mine. If the object has a blank method, it is called. or_if_blank can be called with an normal argument or a block.

"".or_if_blank(:something_else) #=> :something_else

[].or_if_blank { something_expensive_that_returns("hello") } #=> "hello"

"not blank".or_if_blank(42) #=> "not blank"

Soft send

This is like try. It sends the method if the object responsds to the method, otherwise it returns nil. Use like send.

Stdout extensions

It bothers me that p, puts, print, and pp all return nil. This patch makes them return their arguments, which allows you to wrap anything with p(...) and it’ll still work.


5 + p(5) #=> 10
# 5

Additionally, sometimes there’s a puts left somewhere in your code and you’d really like to know where that stdout noise is coming from. Enter Kernel.trace_output:

Kernel.trace_output = true
puts "hello"
#test.rb:4:in `puts'
#hello

Fixnum extensions

5.of {rand}

This gives you five random numbers. It’s like Fixnum.times, but maps the return values instead of returning the number.

String extensions

TODO: documentation

Hash extensions

TODO: documention

Float extension

TODO: documentation

Array extensions

TODO: documentation

ActiveRecord extensions

TODO: documentation