Zucker (pronunciation) is the German word for sugar. It adds syntactic sugar in the form of independent, small scripts that make Ruby even more sweet. It adds a lot of useful helper methods for an improved readability and usage. Everything is documented on this page.
Read this blog post for some more examples. See the github wiki for discussion and information about contributing.
gem install zucker # might need sudo
require 'zucker/all'
The gem consists of many small snippets, called cubes, which are bundled in packages. Since there aren't any dependencies within the gem, you can easily require only the packages or cubes you want:
require 'zucker/cube_or_package_name'
Object.to_proc extensions to use with &.
Furthermore, there are two meta packages available: all simply requires all cubes and default requires all cubes except debug.
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 very critical bugs).
Info, RubyVersion, RubyEngine, OS, Infinity, NaN, alias_for, aliases_for, egonil, nn, iterate, instance_variables_from, ivars, activate_warnings!, deactivate_warnings!, executed_directly?, standalone?, library?, ignore_sigint!, sandbox, tap_on, make_new, (blank?, present?, mcopy)
| Summary | Creates a block, where nil does not raise NoMethodErrors. |
|---|---|
| Methods/Usage | egonil, nnegonil do nil.some_methods.that[:do].not.exist end # => nil nn{ nil.some_methods.that[:do].not.exist } # => nil |
| Information | See this post for more information and discussion. |
| Specification | (show)
require 'zucker/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 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)
require 'zucker' # code by Yohan, slightly edited and comments by me def egonil(&block) # grip methods ori_method_missing = NilClass.instance_method(:method_missing) catch_method_missing = NilClass.instance_method(:catch_method_missing) # activate ego mode NilClass.send :define_method, :method_missing, catch_method_missing # run code yield ensure # no matter what happens: restore default nil behaviour NilClass.send :define_method, :method_missing, ori_method_missing end # this is the ego nil class NilClass def catch_method_missing(m, *args, &block) nil end end alias nn egonil # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| 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 | iterateiterate [1,2], [3,4,5] do |e,f| puts "#{e},#{f}" end # outputs # 1,3 # 2,4 # ,5 |
| Specification | (show)
require 'zucker/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)
require 'zucker' def iterate(*params) # params.shift.zip(*params).each{ |*elements| yield *elements } raise ArgumentError, "wrong number of arguments (0)" if params.empty? first = params.shift if params.empty? # single param - like each if block_given? first.map{|e| yield e } else first.map.to_enum end else # multiple params max_size = [first, *params].max_by(&:count).size padded_first = first.to_a + [nil]*(max_size - first.count) # 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 |
| Discussion | github wiki |
| Summary | Some useful general shortcut methods. |
|---|---|
| Why? | Readability. |
| Methods/Usage | activate_warnings!activate_warnings! # sets $VERBOSE to 1deactivate_warnings!deactivate_warnings! # sets $VERBOSE to 0executed_directly?, standalone?executed_directly? # checks, if the current file is run directly -> truelibrary?library? # checks, if the current file is run directly -> falseirb?irb? # returns false if not called from IRBignore_sigint!ignore_sigint! # blocks CTRL+C |
| Specification | (show)
require 'zucker/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 'library?' do it 'should return false if the file is invoked directly' do library?.should == ( __FILE__ != $PROGRAM_NAME ) end end describe 'executed_directly?' do it 'should return true if the file is invoked directly' do executed_directly?.should == ( __FILE__ == $PROGRAM_NAME ) end end describe 'irb?' do it 'should return true if called in IRB' do; end end describe 'ignore_sigint!' do it 'should catch ctrl+c signals' do; end end # J-_-L |
| Source | (show)
require 'zucker' module Kernel private def activate_warnings! $VERBOSE = true end def deactivate_warnings! $VERBOSE = false end def library? caller[0].rindex(/:\d+(:in `.*')?$/) $PROGRAM_NAME != $` # __FILE__ end def executed_directly? caller[0].rindex(/:\d+(:in `.*')?$/) $PROGRAM_NAME == $` # __FILE__ end alias standalone? executed_directly? def irb? !!(( IRB and $0 == 'irb' ) rescue nil) end def ignore_sigint! # ctrl+c Signal.trap *%w|SIGINT IGNORE| end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Creates a sandbox area. |
|---|---|
| Why? | Ruby comes with sandboxes, but they are hidden (-> integrated) in the $SAFE concept. |
| Methods/Usage | sandboxsandbox do # dangerous commands throw SecurityErrors ($SAFE=4) end # everything's normal again sandbox( lambda{} ) do # no Exception is thrown, if non-nil parameter is passed end # if it is a proc, it will be run instead, if an SecurityError gets raised |
| Specification | (show)
require 'zucker/sandbox' describe 'sandbox' do it 'should throw a SecurityError if bad commands are issued' do proc do sandbox do `ls` end end.should raise_exception SecurityError end it 'should not throw an exception for errors, if the given parameter is not nil' do proc do sandbox( true ) do `ls` end end.should_not raise_exception end it 'should run the proc passed as parameter for errors, if it is given' do sandbox( lambda{|e| e.class } ) do `ls` end.should == SecurityError end end |
| Source | (show)
require 'zucker' module Kernel private def sandbox(rescueblock_or_default=nil) Thread.start do $SAFE = 4 yield end.value rescue SecurityError => e if !rescueblock_or_default.nil? if rescueblock_or_default.is_a? Proc rescueblock_or_default.call e else rescueblock_or_default end else raise e end end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | This cube adds the two tap variants tap_on (known as returning in ActiveSupport) and make_new. |
|---|---|
| Methods/Usage | tap_ontap_on [1,2] do |obj| obj[4] => 5 end #=> [1, 2, nil, nil, 5] make_newmake_new Hash do |obj| obj[1] = 2 end #=> {1 => 2} |
| Information | Read more about using tap on the ruby best practices blog. |
| Specification | (show)
require 'zucker/tap' describe 'tap_on' do it 'should call tap on the argument and apply the block' do obj = "an_object" block = :reverse.to_proc tap_on( obj, &block ).should == obj.tap( &block ) end end describe 'make_new' do it 'should create a new instance of the class given as argument, apply the block on it and return result' do res = make_new Hash do |obj| obj[1] = 2 end res.should == { 1=>2 } end end |
| Source | (show)
require 'zucker' def tap_on(obj, &block) obj.tap &block end def make_new(what, *args, &block) what.new(*args).tap &block end # J-_-L |
| Compatibility | 1.9 |
| Discussion | github wiki |
| Summary | Adds a RubyEngine class for easy compatibility checks. |
|---|---|
| Methods/Usage | RubyEngine# outputs the interpreter nameRubyEngine.mri?RubyEngine.mri? # true if using the official Ruby interpreter RubyEngine.jruby?RubyEngine.jruby? # true if using JRuby RubyEngine.rubinius?RubyEngine.rubinius? # true if using rubinius RubyEngine.ree?RubyEngine.ree? # true if using enterprise edition RubyEngine.ironruby?RubyEngine.ironruby? # true if using IronRuby RubyEngine.macruby?RubyEngine.macruby? # true if using MacRuby RubyEngine.cardinal?RubyEngine.cardinal? # true if using parrot |
| Specification | (show)
require 'zucker/engine' describe 'RubyEngine' do it 'should display the current ruby interpreter (to_s)' do RubyEngine end it 'should create many method aliases for asking for a specific interpreter' do # please see the source or description file end end |
| Source | (show)
require 'zucker' module RubyEngine # try to guess the interpreter @interpreter = case when RUBY_PLATFORM == 'parrot' 'cardinal' when Object.const_defined?(:RUBY_ENGINE) if RUBY_ENGINE == 'ruby' if RUBY_DESCRIPTION =~ /Enterprise/ 'ree' else 'mri' end else RUBY_ENGINE.to_s # jruby, rbx, ironruby, macruby, etc. end else # probably 1.8 'mri' end class << self def is?(what) what === @interpreter end alias is is? def to_s @interpreter.to_s end # ask methods def mri? RubyEngine.is? 'mri' end alias official_ruby? mri? alias ruby? mri? def jruby? RubyEngine.is? 'jruby' end alias java? jruby? def rubinius? RubyEngine.is? 'rbx' end alias rbx? rubinius? def ree? RubyEngine.is? 'ree' end alias enterprise? ree? def ironruby? RubyEngine.is? 'ironruby' end alias iron_ruby? ironruby? def cardinal? RubyEngine.is? 'cardinal' end alias parrot? cardinal? alias perl? cardinal? end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Access environment information with the Info module. |
|---|---|
| Why? | You don't need to remember in which global variable, constant or special method the information you are searching for is hidden. |
| Methods/Usage | Info# for example Info.working_directory # Dir.pwd Info.load_path # $: Info.platform # RUBY_PLATFORM Info.current_file # similar to __FILE__ # you could also add them to the global namespace with: include Info # see the source file for the list of accessors or Info.list |
| Information | Please note that it is not possible to put some of __THOSE_KEYWORDS__ in methods, so the result might slightly differ. This might affect current_file, current_file_directory, current_line and current_method.Thanks to Facets for the caller Regexp. |
| Specification | (show)
require 'zucker/info' describe 'Info' do it 'should define accessors for global variables, constants and some special methods/keywords' do # see sourcefile for the list end end |
| Source | (show)
require 'zucker' require 'rbconfig' require 'etc' module Info class << self # hash like access def [](what) send what end # list available info methods def list singleton_methods - [:[], :list, '[]', 'list'] end end module_function # input def last_input_file $FILENAME end def last_input_line_number $. end def last_input $_ end # program def program_name $0 end def program_arguments $: end def loaded_programs $" end def program_data ::DATA end def child_program_status $CHILD_STATUS end # system info def environment ::ENV end alias env environment def working_directory Dir.pwd end def platform ::RUBY_PLATFORM end def os RbConfig::CONFIG['host_os'] end def process_id $$ end def load_path $: end # user def user_login Etc.getlogin end def user_name Etc.getpwnam(user_login).gecos.split(',')[0] end # current def current_file # __FILE__ return $` if caller[0].rindex(/:\d+(:in `.*')?$/) end def current_file_directory if current_file[0,1] == '(' && current_file[-1,1] == ')' current_file else File.dirname(current_file) end end def current_line # __LINE__ return $1.to_i if caller[0].rindex( /:(\d+)(:in `.*')?$/ ) end def current_method # __method__ (except aliases) return $1.to_sym if caller(1)[0].rindex( /\`([^\']+)\'/ ) end def current_callstack caller end # dealing with strings def gets_separator $/ end def join_separator $, end def print_separator $, end def split_separator $; end # misc def security_level $SAFE end def warnings_activated? $VERBOSE end def debug_activated? $DEBUG end def last_exception $! end # defined objects def global_variables Object.send :global_variables end def global_constants Object.constants end # encoding (1.9) #def source_encoding # __ENCODING__ #end def external_encoding Encoding.default_external end def internal_encoding Encoding.default_internal end # ruby version info def ruby_version # also see the RubyVersion cube ::RUBY_VERSION end def ruby_patchlevel ::RUBY_PATCHLEVEL end def ruby_description ::RUBY_DESCRIPTION end def ruby_release_date ::RUBY_RELEASE_DATE end def ruby_engine # warning! not support by every implementation. It's saver to use the RubyEngine cube ::RUBY_ENGINE end end |
| Compatibility | 1.9, 1.8 (not all information) |
| Discussion | github wiki |
| Summary | Detect the operating system. |
|---|---|
| Why? | Checking for RUBY_PLATFORM does not report the OS when using JRuby and for better readability. |
| Methods/Usage | OS# displays the operating systemOS.linux?OS.linux? # true if you are on a linux machine OS.mac?OS.mac? # true for macs OS.bsd?OS.bsd? # true for bsds OS.windows?include OS; windows? # true for windows. Example of including OS to get the os methods into the global namespace OS.solaris?OS.solaris? # true for solaris/sunos OS.posix?OS.posix? # true if system is posix compatible OS.is?OS.is? /win/ # matches the regex against the os string |
| Information | This cube depends on system information and may not be 100% accurate. Syntax and semantic inspired by Roger Pack's os gem. |
| Specification | (show)
require 'zucker/os' describe 'OS' do it 'should display the used operation system (to_s)' do; end end describe 'linux?' do it 'should return true if OS is a linux' do; end end describe 'mac?' do it 'should return true if OS is a mac or darwin' do; end end describe 'bsd?' do it 'should return true if OS is a bsd' do; end end describe 'windows?' do it 'should return true if OS is a windows' do; end end describe 'solaris?' do it 'should return true if OS is a solaris or sunos' do; end end describe 'posix?' do it 'should return true if OS is posix compatible' do; end end describe 'OS.is?' do it "should test if RbConfig::CONFIG['host_os'] matches the regex (boolean value)" do OS.is?(/linux/).should == !!( RbConfig::CONFIG['host_os'] =~ /linux/ ) end end |
| Source | (show)
require 'zucker' require 'rbconfig' module OS class << self def is?(what) what === RbConfig::CONFIG['host_os'] end alias is is? def to_s RbConfig::CONFIG['host_os'] end end module_function def linux? OS.is?( /linux|cygwin/ ) end def mac? OS.is?( /mac|darwin/ ) end def bsd? OS.is?( /bsd/ ) end def windows? OS.is?( /mswin|win|mingw/ ) end def solaris? OS.is?( /solaris|sunos/ ) end def posix? linux? or mac? or bsd? or solaris? or begin fork do end true rescue NotImplementedError, NoMethodError false end end #def symbian? #TODO who knows what symbian returns? #end # ... end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Adds a RubyVersion class for easy compatibility checks. |
|---|---|
| Methods/Usage | RubyVersion# return RUBY_VERSION RubyVersion # check for the main version with a Float RubyVersion.is? 1.8 # use strings for exacter checking RubyVersion.is.above '1.8.7' RubyVersion.is.at_least '1.8.7' # or exactly, below, at_most # you can use the common comparison operators RubyVersion >= '1.8.7' RubyVersion.between? '1.8.6', '1.8.7' # relase date checks RubyVersion.is.older_than Date.today RubyVersion.is.newer_than '2009-08-19' # accessors RubyVersion.major # e.g. => 1 RubyVersion.minor # e.g. => 8 RubyVersion.tiny # e.g. => 7 RubyVersion.patchlevel # e.g. => 249 RubyVersion.description # e.g. => "ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]" |
| Information | Thanks to Hanmac for a nice improvement. |
| Specification | (show)
require 'zucker/version' require 'date' describe 'RubyVersion' do before :all do @remember_version = RUBY_VERSION capture_stderr{ RUBY_VERSION = '1.8.7' } end it 'should display RUBY_VERSION if called directly (to_s)' do RubyVersion.to_s.should == '1.8.7' end context 'using is method with parameter' do it 'should check for main version (1.8 or 1.9) when Float paramater is given' do RubyVersion.is?( 1.8 ).should == true RubyVersion.is?( 1.9 ).should == false end it 'should check with string comparison if parameter is not Float' do RubyVersion.is?( '1.8' ).should == false end end context 'using is method without parameter but method chaining' do it 'should return a string for usage with comparison operators' do (RubyVersion.is > '1.8.7').should == false (RubyVersion <= '1.8.7').should == true (RubyVersion.is.between? '1.8.6', '1.8.7').should == true end it 'should create some handy compare aliases' do RubyVersion.is.above( '1.8.7' ).should == false RubyVersion.is.at_least( '1.8.7' ).should == true RubyVersion.is.exactly( '1.8.7' ).should == true end it 'also allows to check for the release dates' do RubyVersion.is.older_than( Date.today ).should == true RubyVersion.is.newer_than( '2000-01-01' ).should == true end end it 'should define some accessors' do RubyVersion.major.should == 1 RubyVersion.minor.should == 8 RubyVersion.tiny.should == 7 # RubyVersion.patchlevel # => RUBY_PATCHLEVEL # RubyVersion.description # => RUBY_DESCRIPTION end after :all do capture_stderr{ RUBY_VERSION = @remember_version } end end |
| Source | (show)
require 'zucker' require 'date' require 'time' module RubyVersion class << self def to_s RUBY_VERSION end # comparable def <=>(other) value = case other when Integer RUBY_VERSION.to_i when Float RUBY_VERSION.to_f when String RUBY_VERSION when Date, Time other.class.parse(RUBY_RELEASE_DATE) else other = other.to_s RUBY_VERSION end value <=> other end include Comparable # chaining for dsl-like language def is?(other = nil) if other RubyVersion == other else RubyVersion end end alias is is? # aliases alias below < alias below? < alias at_most <= alias at_most? <= alias above > alias above? > alias at_least >= alias at_least? >= alias exactly == alias exactly? == def not(other) self != other end alias not? not alias between between? # compare dates def newer_than(other) if other.is_a? Date or other.is_a? Time RubyVersion > other else RUBY_RELEASE_DATE > other.to_s end end alias newer_than? newer_than def older_than(other) if other.is_a? Date or other.is_a? Time RubyVersion < other else RUBY_RELEASE_DATE < other.to_s end end alias older_than? older_than def released_today RubyVersion.date == Date.today end alias released_today? released_today # accessors def major RUBY_VERSION.to_i end alias main major def minor RUBY_VERSION.split('.')[1].to_i end alias mini minor def tiny RUBY_VERSION.split('.')[2].to_i end alias teeny tiny def patchlevel RUBY_PATCHLEVEL end def platform RUBY_PLATFORM end def release_date Date.parse RUBY_RELEASE_DATE end alias date release_date def description RUBY_DESCRIPTION end end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Methods one could miss for Array. |
|---|---|
| Why? |
|
| 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 'zucker/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)
require 'zucker' class Array def ^(other) # TODO: more efficient (self - other) + (other - self) end # can take an argument & block to be Rails compatible def sum(identity = 0, &block) # inject(:+) if block_given? map(&block).sum( identity ) else inject(:+) || identity end end def chrs self.pack 'C*' end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Enumerable extensions. |
|---|---|
| Methods/Usage | Enumerable#mash[1,2,3].mash{|e| [e, e.to_s] } # => {1=>'1',2=>'2',3=>'3'} |
| Information | Inspired by Ruby Facets' mash. |
| Specification | (show)
require 'zucker/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)
require 'zucker' module Enumerable def mash ret = {} each{ |kv| ret.store *( yield(kv)[0,2] ) } ret end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Some sugar for dealing with hashs. |
|---|---|
| Methods/Usage | Hash.zipHash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6} Hash#<<{1=>2} << [3, 4] # => { 1=>2, 3=>4 }
{1=>2} << { 5=>6 } # => { 1=>2, 5=>6 }
Hash#&{ 1=>4, 2=>5, 3=>6 } & { 1=>4, 2=>7 } # => { 1=>4 } |
| Information | Some of the operators are inspired by Ruby Facets. |
| Specification | (show)
require 'zucker/hash' describe 'Hash.zip' do it 'should zip together both given enumerables and take them as key=>values for a new hash' do Hash.zip( [1,2,3], [4,5,6] ).should == { 1=>4, 2=>5, 3=>6 } end end describe 'Hash#<<' do it 'should append new elements to the hash' do a = { 1=>4, 2=>5, 3=>6 } a << { 4=>7 } a << [5, 8] a.should == { 1=>4, 2=>5, 3=>6, 4=>7, 5=>8 } end end describe 'Hash#&' do it 'should select a sub hash containt only equal key-value pairs' do a = { 1=>4, 2=>5, 3=>6 } b= { 1=>4, 2=>7 } (a & b).should == { 1=>4 } end end |
| Source | (show)
require 'zucker' class Hash def self.zip(keys,values) Hash[ *keys.zip( values ).flatten ] end def <<(other) case when other.is_a?(Hash) merge! other when other.is_a?(Enumerable) || other.respond_to?(:to_splat) merge! Hash[*other] else raise TypeError, 'can only append other Hashs and Enumerables (or Classes that implement to_splat)' end end def &(other) Hash[ *select{ |k,v| other[k] == v }.flatten ] end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | String extensions. |
|---|---|
| Why? | Strings cannot be comfortable enough ;). |
| Methods/Usage | String#-'1234abc5678' - 'b' - /\d/ # => ac String#^'Yes vs No'^7 # => 'No' String#lchomp' Yes'.lchomp # => 'Yes' String#lchomp!# mutable lchomp versionString#ords'Hallo'.ords # => [72, 97, 108, 108, 111] String#constantize'Object'.constantize # => Object 'Spec::VERSION'.constantize # => Spec::VERSION if rspec is loaded # you can also pass a parameter or block to define what happens, when constant does not exist 'IdontExist'.constantize(Array) # => Array 'String5'.constantize do |string| string.chop.constantize end # => String |
| Information | constantize is an improved version of ActiveSupport's one. |
| Specification | (show)
require 'zucker/string' describe 'String#-' do it 'should remove the applied Regexp or String from self via gsub' do ('1234abc5678' - 'b' - /\d/).should == 'ac' end end 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 describe 'String#constantize' do it 'should return the constant with that name' do 'Object'.constantize.should == Object end it 'should also work for nested constants' do 'Spec::VERSION'.constantize.should == Spec::VERSION end it 'should throw name error if constant does not exist (and no parameter is given)' do proc do 'ObfsefsefsefafesafaefRubyZuckerafdfselijfesject'.constantize end.should raise_exception NameError end it 'should call the block (and not raise an error) if constant does not exist and block given' do proc do 'ObfsefsefsefafesafaefRubyZuckerafdfselijfesject'.constantize do |string| Default = [1,2,3] end.should == [1,2,3] end.should_not raise_exception NameError end it 'should return the second parameter (and not raise an error) if constant does not exist and parameter given' do proc do 'ObfsefsefsefafesafaefRubyZuckerafdfselijfesject'.constantize(Array).should == Array end.should_not raise_exception NameError end end end |
| Source | (show)
require 'zucker' class String def -(rem) gsub( Regexp === rem ? rem : rem.to_s, '' ) end def ^(pos) pos = pos.to_i if pos >= 0 self[pos..-1] else self[0...pos] end end def lchomp(arg = $/) reverse.chomp(arg).reverse end def lchomp!(arg = $/) reverse.chomp!(arg).reverse end def ords unpack 'C*' # bytes.to_a end def constantize(default_value = nil) # always uses global scope as in AS... is this good? get_constant = lambda{ self.split(/::/).inject( Object ){ |base_constant, current_constant| base_constant.const_get current_constant } } if !default_value && !block_given? get_constant.call else begin get_constant.call rescue NameError if block_given? yield self else default_value end end end end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| 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 |
| Information | Inspired by (I've seen the unary + for Symbol somewhere on the net... but cannot remember where...) |
| Specification | (show)
require 'zucker/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)
require 'zucker' 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) |
| Discussion | github wiki |
| 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 'zucker/union' shared_examples_for "Regexp.union operator" do it "should create an Regexp.union of both operands" do (/Ruby\d/ | /test/i | "cheat").should == Regexp.union( Regexp.union( /Ruby\d/, /test/i ), "cheat" ) end end describe 'Regexp#|' do it_should_behave_like 'Regexp.union operator' end describe 'String#|' do it_should_behave_like 'Regexp.union operator' end |
| Source | (show)
require 'zucker' 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 |
| Discussion | github wiki |
| 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 |
| Specification | (show)
require 'zucker/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)
require 'zucker' 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 |
| Discussion | github wiki |
| 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#mcopya = %w[hello world]
b = a.mcopy
|
| Specification | (show)
require 'zucker/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)
require 'zucker' class Object def mcopy Marshal.load Marshal.dump self end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | not returns an object on which all methods are redirected to it's receiver object, but returns inverted boolean. |
|---|---|
| Why? | Better readability. |
| Methods/Usage | Object#not[1,2,3].not.empty? # true |
| Information | See this article by Jay Field for more information. |
| Specification | (show)
require 'zucker/not' describe 'Object#not' do it "should return an object on which all methods are redirected to it's receiver object, but return an inverted boolean" do [1,2,3].not.empty?.should == true nil.not.nil?.should == false end end |
| Source | (show)
require 'zucker' class Object def not NotClass.new self end class NotClass < BasicObject def initialize(receiver) @receiver = receiver end def method_missing(m, *args, &block) not @receiver.public_send( m, *args, &block ) end end end # J-_-L |
| Compatibility | 1.9 |
| Discussion | github wiki |
| 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 &[:*, 5] # => [5, 10, 15, 20] # you can also chain them, if the first parameter is an Array [1,2,3,4].map &[[:to_s, 2],[:+, 'b']] # => ["1b", "10b", "11b", "100b"] |
| Information | Inspired by this article. More about to_proc. Chaining inspired by eregon. |
| Specification | (show)
require 'zucker/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 it "should convert each element to a proc and chain it, if the first parameter is an array" do [1,2,3,4].map( &[[:*,2],[:+,4]] ).should == [1,2,3,4].map{|i| i*2 + 4 } end end |
| Source | (show)
require 'zucker' class Array def to_proc Proc.new{ |obj| if self.first.is_a? Array self.inject(obj){ |result, nested_array| nested_array.to_proc.call result } else obj.send *self end } end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| 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] ] |
| Information | Inspired by Ruby Facets. More about to_proc. |
| Specification | (show)
require 'zucker/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)
require 'zucker' class Class def to_proc Proc.new do |*args| self.new *args end end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| 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'] |
| Information | More about to_proc. |
| Specification | (show)
require 'zucker/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)
require 'zucker' 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 |
| Discussion | github wiki |
| 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"] |
| Information | More about to_proc. |
| Specification | (show)
require 'zucker/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)
require 'zucker' class Regexp def to_proc proc do |e| e.to_s[self] end end end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | A different way to create aliases: Reversed order and you can pass multiple alias names. |
|---|---|
| Why? | It's clearer in which order to put the arguments. |
| Methods/Usage | alias_for, aliases_foralias_for :methods, :ms # creates an alias for the method :methods with the name ms module Enumerable aliases_for :zip, :with, :% end # creates multiple aliases Module#method_alias_for, Module#method_aliases_for# same as alias_for, but using Module#alias_method instead of alias
|
| Information | Thanks to Kristian Mandrup for the idea and alias method specs. |
| Specification | (show)
require 'zucker/alias_for' describe 'alias_for' do it 'should create an alias for global methods' do # rspec bug? # def m1 # 1 # end # alias_for :m1, :a1 # # proc do # a1.should == 1 # end.should_not raise_exception end it 'should create an alias for instance methods' do class Array def m2 2 end alias_for :m2, :a2 end proc do [1,2,3].a2.should == 2 end.should_not raise_exception end it 'should create an alias for class (singleton) methods' do class Array class << Array def m3 3 end alias_for :m3, :a3 end end proc do Array.a3.should == 3 end.should_not raise_exception end it 'should create aliases for the first argument with all other arguments' do class Object def m4 4 end alias_for :m4, :ma, :mb, :mc end proc do 1.ma.should == 4 "1".mb.should == 4 [1].mc.should == 4 end.should_not raise_exception end end # alias_method module Blip def blip 'blip' end alias_methods_for :blip, :blap, :blup class << self def self_blip 'blip' end alias_methods_for :self_blip, :self_blap, :self_blup end end class Hello include Blip def hello 'hello' end alias_methods_for :hello, :hi, :howdy class << self def self_hello 'hello' end alias_methods_for :self_hello, :self_hi, :self_howdy end end describe 'alias_methods_for' do let(:h) { Hello.new } context "module context" do it "should alias instance methods" do h.blap.should == h.blip h.blup.should == h.blip end it "should alias class methods" do Blip.self_blap.should == Blip.self_blip Blip.self_blup.should == Blip.self_blip end end context "class context" do it "should alias instance methods" do h.hi.should == h.hello h.howdy.should == h.hello end it "should alias class methods" do Hello.self_hi.should == Hello.self_hello Hello.self_howdy.should == Hello.self_hello end end end |
| Source | (show)
require 'zucker' def alias_for(m, *aliases) aliases.each{ |a| class_eval "alias #{a} #{m}" } end alias aliases_for alias_for class Module def alias_method_for(m, *alias_methods) alias_methods.each{ |a| class_eval do alias_method a.to_sym, m.to_sym end } end alias alias_methods_for alias_method_for end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Some convenient aliases (and constants) for existing methods. |
|---|---|
| Methods/Usage | Object#is_an?Object.is_a?Enumerable#withEnumerable#zip Enumerable#%Enumerable#zip Array#**Array#product Hash#+Hash#merge Binding#[]Binding#eval File.filenameFile.basenameDir.joinFile.joinDir.splitFile.splitInfinity1.0 / 0.0 NaN0.0 / 0.0 |
| Specification | (show)
require 'zucker/aliases' describe '(aliases)' do it 'should create these aliases' do # see aliases.rb for aliase list end it 'should define these constants' do Infinity.finite?.should == false NaN.nan?.should == true end end |
| Source | (show)
require 'zucker' class Object alias is_an? is_a? # thanks to utility_belt end module Enumerable alias with zip alias % zip end class Array alias ** product alias contains? include? end class String alias contains? include? end class Hash alias + merge end class Binding #alias [] eval def [](expr) self.eval "#{expr}" end end class << File alias filename basename # thanks rdp :) end class << Dir def join(*args) File.join(*args) end def split(*args) File.split(*args) end end # constants - who would use these in real-world code for other things? Infinity = 1.0 / 0.0 # or 2*Float::MAX or Float::INFINITY NaN = 0.0 / 0.0 # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| 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) |
| Methods/Usage | instance_variables_from, ivarsdef 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 'zucker/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)
require 'zucker' 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 |
| Discussion | github wiki |
| Summary | This helper methods defines [] and []= for accesing an instance variable. |
|---|---|
| Methods/Usage | square_brackets_forclass 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 'zucker/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)
require 'zucker' class Module def square_brackets_for(ivar, assignment = true) # undef [] if respond_to? :[] # undef []= if respond_to? :[]= 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 |
| Discussion | github wiki |
(not included by require 'zucker/default')
| Summary | Adds a verbose Binding#inspect. |
|---|---|
| Why? | It gives you information about the current environment variables. |
| Methods/Usage | Binding#inspect, v, vv# shows your current environment's variables, irb example: >> a=3 => 3 >> binding => #<Binding:0x94c4b50> local vars - a: 3 - _: #<Binding:0x94c4b50> (instance vars) - none self - main block_given? - false |
| Specification | (show)
require 'zucker/binding' describe 'Binding#inspect' do it 'should output the current environment' do; end end |
| Source | (show)
require 'zucker' class Binding def inspect put_vars = lambda { |array| if array.empty? ' - none' else array.map{|e| val = self.eval "#{e}" val = val.is_a?( Binding ) ? val.to_s : val.inspect " - #{e}: #{ val }" }.join "\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 alias v binding alias vv binding # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | c outputs the current method callstack. |
|---|---|
| Methods/Usage | c, ccc # shows the method callstack c true # do not hide irb callstack |
| Specification | (show)
require 'zucker/cc' describe 'c' do it 'should output the method callstack' do; end end |
| Source | (show)
require 'zucker' module Kernel private def c(show_irb = false) method_stack = caller.reverse.map{ |m| m.rindex( /:\d+(:in `(.*)')?$/ ) $2 }.compact if !show_irb && a = method_stack.index( 'irb_binding' ) method_stack = [ method_stack[0], '(irb)', *method_stack[a+1..-1] ] end # puts method_stack.map.with_index{ |m, i| method_stack.each_with_index{ |m, i| puts " "*i + m } end alias cc c end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | Easy debug printing with the p alternative .d. It outputs to stdout and returns self. Accepts a block. |
|---|---|
| Methods/Usage | Object#d, Object#ddsome.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' |
| Information | This is inspired by the .tap method.There is also tap cube with more tap methods. |
| Specification | (show)
require 'zucker/dd' 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 capture_stdout do a.each{ |e| (e.d).should == e } a.each{ |e| (e.d{|value| "This is a: #{value}"}).should == e } end end it "should puts .inspect if no block is given (and not change the object's value)" do capture_stdout do a[0].d a[1].d a[6].d end.should == %{1\n"1"\ntrue\n} end it "should puts the block if it is given (and not change the object's value)" do capture_stdout do a[0].d{|value| "This is a: #{value}"} a[1].d{|value| "This is a: #{value}"} a[6].d{|value| "This is a: #{value}"} end.should == %{This is a: 1\nThis is a: 1\nThis is a: true\n} end end |
| Source | (show)
require 'zucker' 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 alias dd d end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | m displays an ordered public method list. |
|---|---|
| Why? | See one object's methods without those rarely used inherited methods. |
| Methods/Usage | Object#m, Object#mm, Object#method_list'test'.m 2 # outputs the list (2 levels deep), for example: String [:<=>, :==, :===, :eql?, :hash, :casecmp, :+, :*, :%, :[], :[]=, :insert, :length, :size, :bytesize, :empty?, :=~, :match, :succ, :succ!, :next, :next!, :upto, :index, :rindex, :replace, :clear, :chr, :getbyte, :setbyte, :to_i, :to_f, :to_s, :to_str, :inspect, :dump, :upcase, :downcase, :capitalize, :swapcase, :upcase!, :downcase!, :capitalize!, :swapcase!, :hex, :oct, :split, :lines, :bytes, :chars, :codepoints, :reverse, :reverse!, :concat, :<<, :crypt, :intern, :to_sym, :ord, :include?, :start_with?, :end_with?, :scan, :ljust, :rjust, :center, :sub, :gsub, :chop, :chomp, :strip, :lstrip, :rstrip, :sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr, :tr_s, :delete, :squeeze, :count, :tr!, :tr_s!, :delete!, :squeeze!, :each_line, :each_byte, :each_char, :each_codepoint, :sum, :slice, :slice!, :partition, :rpartition, :encoding, :force_encoding, :valid_encoding?, :ascii_only?, :unpack, :encode, :encode!, :to_r, :to_c, :blank?, :^, :lchomp, :lchomp!, :ords, :constantize, :+@, :-@, :|] Comparable [:==, :>, :>=, :<, :<=, :between?] |
| Information | See this article for more information. |
| Specification | (show)
require 'zucker/mm' describe 'Object#mm' do it 'should display an ordered method list' do; end end |
| Source | (show)
require 'zucker' module Kernel def m(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 m alias method_list m end # J-_-L |
| Compatibility | 1.9, 1.8 (returns strings instead of symbols) |
| Discussion | github wiki |
| Summary | The o method outputs the current method, line, file and label (if given). |
|---|---|
| Methods/Usage | o, ooo # e.g: Reached method `irb_binding', line 1 of file (irb) o:Label # e.g: Label: reached method `abc', line 7 of file (irb) |
| Specification | (show)
require 'zucker/oo' describe 'o' do it 'should output the current line, file, method and label (if given)' do; end end |
| Source | (show)
require 'zucker' module Kernel private def o(desc = nil) caller[0].rindex( /:(\d+)(:in (`.*'))?$/ ) m = $3 ? "method #$3, " : "" d = desc ? "#{desc}: r" : 'R' puts "#{d}eached #{m}line #$1 of file #$`" # [$`, $1.to_i, $3.to_sym, desc] end alias oo o end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
| Summary | The q method does the same like p, but puts out multiple arguments on the same line. |
|---|---|
| Methods/Usage | q, qqq "zucker", '', {6=>7}, 5, 2.3, :o # outputs "zucker" "" {6=>7} 5 2.3 :o |
| Information | Inspired by rdp. |
| Specification | (show)
require 'zucker/qq' describe 'q' do it 'should output the same as p for a single arg' do capture_stdout{p /some object/}.should == capture_stdout{q /some object/} end it "should output the same as p but for multiple args one one line, values separated by two spaces" do capture_stdout do q 1, "1", 2..5, [], {:hallo => :du}, nil, true end.chop.should == capture_stdout do p 1, "1", 2..5, [], {:hallo => :du}, nil, true end.chop.gsub( "\n", ' ' ) end end |
| Source | (show)
require 'zucker' module Kernel private def q(*args) puts args.map( &:inspect )*' ' unless args.empty? end alias qq q end # J-_-L |
| Compatibility | 1.9, 1.8 |
| Discussion | github wiki |
You can activate some additional aliases for Zucker functionality by executing
Zucker.more_aliases! # => [:copy, :n, :init, :returning, :lib?, :RV, :RE]
2010-10-03 | Zucker 6 * no new cubes * bugfix for OS.posix? * small changes + bugfixes + doc improvements * added two user methods to Info * changed egonil semantics ( using method_missing, see http://rbjl.net/26/catch_nil.rb ) * bugfix for vv 2010-09-04 | Zucker 5 * debug edition - added two debug helpers: oo (output line, method, file) and cc (output method callstack) * renamed cube D to dd add added more debug aliases (for mm and binding) * fixed __SPECIAL_VARS__ in info and kernel cube and some minor bugfixes * Zucker.activate_more_aliases! option * added Hash#& * added aliases: File.filename (for basename), Dir.join and Dir.split (for File.join, split) * added a flexible requiring mechansim in zucker.rb (no api changes) * restructered packages * added rake tasks for releasing * improved RubyVersion constant (cleaner and more flexible) 2010-09-01 | Zucker 4 * fixed Binding#inspect * added RubyEngine constant * added RubyVersion constant * added OS constant * added q debug method (like p but on one line) * added String#- 2010-08-14 | Zucker 3 * added tap cube * added Object#not * added alias_for for an alternative alias syntax * added String#constantize (improved AS version) * improved Info module * made Array#sum Rails compatibile * improved docs * changed directory layout (no changes for requiring) * more small changes 2010-08-08 | Zucker 2 * added info cube * added chaining for array2proc * fixed Hash.zip * fixed instance_variables_from binding for 1.9 * more specs 2010-08-06 | Zucker 1 * initial release 2010-08-05 | Zucker 0 * pre-release for rug-b talk