Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
phoet committed Sep 8, 2009
0 parents commit 01fc6af
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
26 changes: 26 additions & 0 deletions README.rdoc
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,26 @@
= I dont give a shit (idgas)

Inspired by groovys questionmark-syntax. 'I dont give a shit' tries to implement this behavior in ruby.

You can put a +?+ behind every method-call to ignore, weather it returns nil.

So chaining of calls within deep data-structures is painless:

some_data_that_might_contain_nil.order?.shoppingcart?.item?.second?.price?

This call would return the price of the second item in the shopping-cart or +nil+ if some of the objects in the data-structure is +nil+ itself.

== Install

$ gem install phoet-idgas -s http://gems.github.com

== How to use

Just require the gem and put it in a place where it can override the default behavior of your script.
You might put it as an initializer in your rails application or something like that.

$ irb -rubygems
require 'i_dont_give_a_shit'

nil.i?.dont?.give?.a?.shit?
=> nil
17 changes: 17 additions & 0 deletions i_dont_give_a_shit.gemspec
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = "i_dont_give_a_shit"
s.version = "0.0.1"
s.rubyforge_project = 'none'

s.author = "Peter Schröder"
s.description = "Helper for handling nil-calls."
s.email = 'phoetmail@googlemail.com'
s.homepage = "http://github.com/phoet/idgas"
s.summary = "If you just dont give a shit about nil add a questionmark to your method-call."

s.has_rdoc = true
s.rdoc_options = ['-a', "--inline-source", "--charset=UTF-8"]
s.extra_rdoc_files = ["README.rdoc"]
s.files = [ "README.rdoc", "lib/i_dont_give_a_shit.rb" ]
s.test_files = [ "test/test_i_dont_give_a_shit.rb" ]
end
37 changes: 37 additions & 0 deletions lib/i_dont_give_a_shit.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,37 @@
# Open up Object to add handling of +?+.
class Object

# Save a reference to original +method_missing+.
alias m_m method_missing

# Catches all calls that were intended to go to the real object ending with +?+.
# The question-mark is stripped and the call is processed again.
# Calls without a question-mark are send to the original +method_missing+.
def method_missing(sym,*args, &block)
method_name = sym.to_s
if /.+\?$/ =~ method_name
puts "object '#{sym}' '#{args}' '#{block}'"
send(method_name[0..-2], *args, &block)
else
puts "object missing '#{sym}' '#{args}' '#{block}'"
m_m(sym,*args, &block)
end
end
end

# Open up Nil to add handling of +?+.
class NilClass

# Catches all calls that were put on nil references ending with +?+ returning nil again.
# Calls without a question-mark are send to original +method_missing+.
def method_missing(sym,*args, &block)
method_name = sym.to_s
if /.+\?$/ =~ method_name
puts "nil '#{sym}' '#{args}' '#{block}'"
self
else
puts "nil missing '#{sym}' '#{args}' '#{block}'"
super.m_m(sym,*args, &block)
end
end
end
53 changes: 53 additions & 0 deletions test/test_i_dont_give_a_shit.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,53 @@
$:.unshift File.join(File.dirname(__FILE__),'..','..','lib')

require "test/unit"
require "i_dont_give_a_shit"

class TestIDontGiveAShit < Test::Unit::TestCase

def test_some_wired_stuff
assert_equal(nil.send(:' ?'), nil)
assert_equal(nil.blow?(nil).up?(nil, nil){}.now?(0,1,3), nil)
end

def test_nil_check_still_works
assert_equal(nil.nil?, true)
assert_equal(''.nil?, false)
end

def test_method_with_questionmark_does_not_blow_up
assert_raise(NoMethodError) { nil.blowup }
nil.blowup?
end

def test_chained_method_with_questionmark_does_not_blow_up
assert_raise(NoMethodError) { nil.blowup?.up?.now }
nil.blowup?.up?.now?
end

def test_call_for_tosomething_works
assert_equal("", nil.to_s)
assert_equal('', nil.is_it_empty?.to_s)
assert_equal(0, nil.is_it_zeor?.to_i)
end

def test_call_with_block_success_does_not_blow_up
nil.some?.block?{puts 'hi'}
nil.some?('a','b','c').block?{puts 'hi'}
end

class Blow
def up
'NOT!'
end
def not
nil
end
end

def test_call_for_existing_methods_works
assert_equal('NOT!', Blow.new.up?.to_s)
assert_equal('', Blow.new?.not?.to_s)
end

end

0 comments on commit 01fc6af

Please sign in to comment.