Today I Learned

hashrocket A Hashrocket project

10 posts by nickpalaniuk twitter @nikkypx

How Sinatra avoids polluting inheritance chain

When you open a new file:

[13] pry(main)> self
=> main
[14] pry(main)> self.class
=> Object

main is an instance of Object

An example: the Sinatra DSL

require 'sinatra'

get '/' do
  'Hello world!'
end

#get is put in main’s singleton class

[1] pry(main)> require 'sinatra'
=> true
[2] pry(main)> method(:get).source_location
=> .../sinatra-1.4.6/lib/sinatra/base.rb", 1987]
pry(main)> Object.new.get
NoMethodError: undefined method `get' for #

This is achieved by extending the singleton class of main.

from Sinatra:

extend Sinatra::Delegator

A simple example:

class Foo
  module DSL
    def foo
      'bar'
    end
  end
end

extend ::Foo::DSL

Ruby objects from YAML

For certain objects if the ISO8601 standard is followed, Ruby will create an instance instead of a string when parsing the value.

> “A date can be represented by its year, month and day in ISO8601 order."

For example:

post.txt

title: Updated
date: 2011-09-25
pry(main)> p = YAML.load(File.new('post.txt'))
=> {"title"=>"Updated", "date"=>#}
pry(main)> p['date'].class
=> Date

http://yaml.org/YAML_for_ruby.html#date

Proc.new inside a method

Typically, you see blocks passed with yield:

def foo
  yield
end
foo { 1 + 1 }
=> 2

or with the explicit to proc (&block ) at the end of your method arguments:

def foo(&block)
  block.call
end
foo { 1 + 1 }
=> 2

Proc.new can be called without a block within a method and it will capture an attached block

def foo
  Proc.new.call
end

foo { 1 + 1 }
=> 2

ruby operators <, >, === etc.

ruby -v 2.2.2

Different implementations of some of these operators can be used to do some cool things.

The #< implementation on Module for example.

> Module < BasicObject
=> true

> Object < Class
=> false

#== and #=== are implemented the same on Fixnum or BigDecimal, but on Module

> a === b

evaluates to true if b is an instance of a or a’s descendants

> (1..10) === 5
=> true

> 5 === (1..10)
=> false

> 'str' === String
=> false

> String === 'str'
=> true

This is the case-equality operator and this behavior can be overridden to customize case statements. An example of overriding.

class Range
  def ===(o)
    puts 'nope sucka'
  end
end

case 5
when(1..10)
'This would normally work'
else
end
=> nope sucka

Quick .vimrc editing and sourcing

Vim will set the MYVIMRC environment variable to the path of your vimrc on startup. You can verify this by running

:! env | grep VIM

This gives us the ability to do quick vimrc editing after adding something like this in your vimrc.

nnoremap ev :vs $MYVIMRC
nnoremap sv :source $MYVIMRC

You could change the to horizontal split if want with :sp, but you get the idea. Don’t forget to source!