Permalink
Browse files

initial

  • Loading branch information...
0 parents commit 01fc6af621aed4896a63df8a08f8022feb85ca71 @phoet committed Sep 8, 2009
Showing with 133 additions and 0 deletions.
  1. +26 −0 README.rdoc
  2. +17 −0 i_dont_give_a_shit.gemspec
  3. +37 −0 lib/i_dont_give_a_shit.rb
  4. +53 −0 test/test_i_dont_give_a_shit.rb
@@ -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
@@ -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
@@ -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
@@ -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.