Ruby Sugar Refinery
The Ruby Sugar Refinery is a collection of tiny refinements (declarative local core extensions) for Ruby.
Setup & Usage
Add to Gemfile:
gem 'sugar_refinery', require: 'sugar_refinery/all'
Then add refinements to the current Ruby file or module:
using SugarRefinery::CamelSnake
using SugarRefinery::HashZip
"ClassName".to_snake # => "class_name"
Hash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6}
List of Refinements
alias_for
Summary | A different way to create aliases: Reversed order and you can pass multiple alias names. The order feels more logical |
---|
Activate |
using SugarRefinery::AliasFor
|
---|
Usage | Module#alias_for, Module#aliases_for
# creates an alias for the method :methods with the name ms
class Object
alias_for :methods, :ms
end
# creates multiple aliases
module Enumerable
aliases_for :zip, :with, :%
end
|
---|
Specification | (show)
require 'sugar_refinery/alias_for'
using SugarRefinery::AliasFor
describe 'alias_for' do
it 'should create an alias for instance methods' do
class Array
def m2
2
end
aliases_for :m2, :a2, :'a-2'
end
proc do
[1,2,3].a2.should == 2
[1,2,3].send('a-2').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{
Array.a3.should == 3
}.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{
1.ma.should == 4
"1".mb.should == 4
[1].mc.should == 4
}.should_not raise_exception
end
it 'works with uncommon chars' do
class Object
alias_for :tainted?, :"tain-ted?"
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module AliasFor
refine Module do
private
def alias_for(m, *aliases)
aliases.each{ |a| class_eval "alias :'#{ a }' :'#{ m }'" }
end
alias aliases_for alias_for
end
end
end
|
---|
array_op
Summary | Operators one could miss for Array |
---|
Activate |
using SugarRefinery::ArrayOp
|
---|
Usage | Array#^
[1,2,3,4] ^ [3,4,5,6] # => [1,2,5,6]
|
---|
Specification | (show)
require 'sugar_refinery/array_op'
using SugarRefinery::ArrayOp
describe 'Array#^' do
it 'does 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#**' do
it 'returns the array product' do
([1,2] ** %w[a b]).should == [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module ArrayOp
refine Array do
def ^(other)
(self - other) + (other - self)
end
def **(*o, &block)
product *o, &block
end
end
end
end
|
---|
array_stats
Summary | Statistics for Array |
---|
Activate |
using SugarRefinery::ArrayStats
|
---|
Usage | Array#mean
# calculates mean (average)
Array#stdev
# calculates standard deviation (takes :sample or :population as argument)
Array#stdev_sample
# calculates sample standard deviation
Array#stdev_population
# calculates population standard deviation
Array#z_score
# calculates standard score
|
---|
Specification | (show)
require "sugar_refinery/array_stats"
using SugarRefinery::ArrayStats
describe "doing statistics on arrays" do
let(:list) { (2..5).to_a }
describe "Array#mean" do
it "should return the average" do
list.mean.should == 3.5
end
end
describe "Array#stdev_sample" do
it "should return the standard deviation of the sample" do
list.stdev_sample.should be_close(1.2909944487358056, 1e-8)
end
end
describe "Array#stdev_population" do
it "should return the standard deviation of the population" do
list.stdev_population.should be_close(1.118033988749895, 1e-8)
end
end
describe "Array#stdev" do
it "should default to population" do
list.stdev.should be_close(list.stdev_population, 1e-8)
end
it "should delegate sample correctly" do
list.stdev(:sample).should be_close(list.stdev_sample, 1e-8)
end
it "should delegate population correctly" do
list.stdev(:population).should be_close(list.stdev_population, 1e-8)
end
it "should raise an error with any other key" do
expect { list.stdev(:pony) }.to raise_error(ArgumentError)
end
end
describe "Array#z_score" do
it "should default to population" do
list.z_score.zip(list.z_score(:population)).each do |value, actual|
value.should be_close(actual, 1e-8)
end
end
it "should delegate sample correctly" do
sample_z_score = [
-1.161895003862225,
-0.3872983346207417,
0.3872983346207417,
1.161895003862225
]
p list
list.z_score(:sample).zip(sample_z_score).each do |value, actual|
value.should be_close(actual, 1e-8)
end
end
it "should delegate population correctly" do
population_z_score = [
-1.3416407864998738,
-0.4472135954999579,
0.4472135954999579,
1.3416407864998738
]
list.z_score(:population).zip(population_z_score).each do |value, actual|
value.should be_close(actual, 1e-8)
end
end
it "should raise an error with any other key" do
expect { list.z_score(:pony) }.to raise_error(ArgumentError)
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module ArrayStats
refine Array do
def mean
inject(&:+) / length.to_f
end
def stdev(type = :population)
case type
when :population then stdev_population
when :sample then stdev_sample
else raise ArgumentError.new("%s is not a valid argument" % type)
end
end
def stdev_sample
Math.sqrt(inject(0.0) { |sum, x| sum + (mean - x) ** 2 } / (length - 1))
end
def stdev_population
Math.sqrt(inject(0.0) { |sum, x| sum + (mean - x) ** 2 } / length)
end
def z_score(type = :population)
map { |x| (x - mean) / stdev(type) }
end
end
end
end
|
---|
blank
Summary | Does pretty the same as in ActiveSupport: Every object can be asked if it is blank or present |
---|
Activate |
using SugarRefinery::Blank
|
---|
Usage | Object#blank?
'an object'.blank? # => false
nil.present? # => false
|
---|
Specification | (show)
require 'sugar_refinery/blank'
using SugarRefinery::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_relative 'version'
module SugarRefinery
module Blank
refine Object do
def blank?
if respond_to? :empty? then empty? else !self end
end
def present?
!blank?
end
end
refine NilClass do
def blank?() true end
end
refine FalseClass do
def blank?() true end
end
refine TrueClass do
def blank?() false end
end
refine Numeric do
def blank?() false end
end
refine Array do
def blank?() empty? end
end
refine Hash do
def blank?() empty? end
end
refine String do
def blank?() self !~ /\S/ end
end
refine Regexp do
def blank?() self == // end
end
end
end
|
---|
camel_snake
Summary | Provides String#to_camel and String#to_snake . |
---|
Activate |
using SugarRefinery::CamelSnake
|
---|
Usage | String#to_camel
'was_snake_string'.to_camel # => 'WasSnakeString'
String#to_snake
'WasCamelString'.to_snake # => 'was_camel_string'
|
---|
Specification | (show)
require 'sugar_refinery/camel_snake'
using SugarRefinery::CamelSnake
describe 'String#to_camel' do
it 'should turn a snake_cased string to CamelCase' do
'was_snake_case'.to_camel.should == 'WasSnakeCase'
end
end
describe 'String#to_snake' do
it 'should turn a CamelCased string to snake_case' do
'WasCamelCase'.to_snake.should == 'was_camel_case'
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module CamelSnake
refine String do
def to_snake
gsub(/(?<!^)[A-Z]/) do "_#$&" end.downcase
end
def to_camel
gsub(/(?:^|_)([a-z])/) do $1.upcase end
end
end
end
end
|
---|
chain_map
Summary | Chain multiple procs on Array elements |
---|
Activate |
using SugarRefinery::ChainMap
|
---|
Usage | Array#chain_map
[-3, -2, -1].chain_map(:abs, :to_s) # => ["3", "2", "1"]
|
---|
Specification | (show)
require "sugar_refinery/chain_map"
using SugarRefinery::ChainMap
describe "Array#chain_map" do
it "should repeatedly chain symbols as map calls" do
list = [-3, -2, -1]
list.chain_map(:abs, :to_s) == %w{3 2 1}
end
it "should repeatedly chain blocks as map calls" do
list = [-3, -2, -1]
list.chain_map(->(e) { e ** 2 }, ->(e) { e * -1 }) == [-9, -4, -1]
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module ChainMap
refine Array do
def chain_map(*args)
args.inject(self) { |collection, action| collection.map(&action) }
end
end
end
end
|
---|
constantize
Summary | Easier handling of dynamic constant names |
---|
Activate |
using SugarRefinery::Constantize
|
---|
Usage | 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 | An improved version of ActiveSupport's one |
---|
Specification | (show)
require 'sugar_refinery/constantize'
using SugarRefinery::Constantize
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
'SugarRefinery::VERSION'.constantize.should == SugarRefinery::VERSION
end
it 'should throw name error if constant does not exist (and no parameter is given)' do
proc do
'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.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
'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.constantize do |string|
Default = [1,2,3]
end.should == [1,2,3]
end.should_not raise_exception
end
it 'should return the second parameter (and not raise an error) if constant does not exist and parameter given' do
proc do
'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.constantize(Array).should == Array
end.should_not raise_exception
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module Constantize
refine String do
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
end
end
|
---|
dir_utils
Summary | Some shortcuts for working with directories |
---|
Activate |
using SugarRefinery::DirUtils
|
---|
Usage | Dir.joinDir.splitDir.rm |
---|
Specification | (show)
require 'sugar_refinery/dir_utils'
require 'securerandom'
using SugarRefinery::DirUtils
describe Dir do
describe '.join' do
it 'delegates to File.join' do
a = %w[some file path]
expect( Dir.join(a) ).to be == File.join(a)
end
end
describe '.split' do
it 'delegates to File.split' do
a = 'some/file/path'
expect( Dir.split(a) ).to be == File.split(a)
end
end
describe '.rm' do
it 'removes directories with content' do
path = "tmp_#{SecureRandom.uuid}"
FileUtils.mkdir path
FileUtils.touch "#{path}/123"
expect{
Dir.rm path
}.not_to raise_error
expect( Dir['*'] ).to_not include(path)
end
end
end
|
---|
Source | (show)
require_relative 'version'
require 'fileutils'
module SugarRefinery
module DirUtils
refine Dir.singleton_class do
def join(*args)
File.join(*args)
end
def split(*args)
File.split(*args)
end
def rm(*args)
FileUtils.rm_r(*args)
end
end
end
end
|
---|
file_force_delete
Summary | File.delete! (like `rm -f`) |
---|
Activate |
using SugarRefinery::FileForceDelete
|
---|
Usage | File.delete!
File.delete! 'some_filename' # will delete the file, don't care if it exist.
|
---|
Information | Idea for File.delete! from sugar-high. |
---|
Specification | (show)
require 'sugar_refinery/file_force_delete'
require 'fileutils'
using SugarRefinery::FileForceDelete
describe File do
describe '.delete!' do
after{ File.delete! 'random_filename' }
let :random_filename do
'test_' + (0..20).map{|e| [*'a'..'z'].sample }*''
end
it 'should delete the filename given as argument if it exists + return non-nil' do
FileUtils.touch random_filename
res = false
proc do
res = File.delete! random_filename
end.should_not raise_exception
res.should be_truthy
end
it 'should do nothing if the filename given as argument does not exist + return nil' do
res = false
proc do
res = File.delete! random_filename
end.should_not raise_exception
res.should be_falsey
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module FileForceDelete
refine File.singleton_class do
def delete!(filename)
return nil if !File.exist?(filename)
File.delete filename
end
end
end
end
|
---|
file_gsub
Summary | Will read the file and substitute the hash keys with their values |
---|
Activate |
using SugarRefinery::FileGsub
|
---|
Usage | File.gsub
File.gsub 'some_filename',
/hi/ => 'cu',
/\d/ => proc{ |m| (m.to_i+1).to_s }
|
---|
Specification | (show)
require 'sugar_refinery/file_gsub'
require 'fileutils'
using SugarRefinery::FileGsub
describe File do
describe '.gsub' do
let :random_filename do
'test_' + (0..20).map{|e| [*'a'..'z'].sample }*''
end
it 'should read filename in arg1, substitute every key in the arg2 with its value and save the file' do
File.open(random_filename,'w'){ |file|
file.print 'should read filename in arg1, substitute every key in the arg2 with its value and save the file'
}
File.gsub random_filename,
/read/ => 'write',
/\d+/ => proc{|m| (m.to_i+1).to_s }
File.read(random_filename).should ==
'should write filename in arg2, substitute every key in the arg3 with its value and save the file'
FileUtils.rm random_filename
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module FileGsub
refine File.singleton_class do
def gsub(filename, regex_hash)
data = File.read filename
File.open(filename,'w'){ |file|
regex_hash.each{ |regex, new_string|
regex = regex.to_s unless regex.is_a? Regexp
if new_string.is_a? Proc
data.gsub! regex, &new_string
else
data.gsub! regex, new_string
end
}
file.print data
}
end
end
end
end
|
---|
hash_op
Summary | Sugar for dealing with hashes |
---|
Activate |
using SugarRefinery::HashOp
|
---|
Usage | 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 'sugar_refinery/hash_op'
using SugarRefinery::HashOp
describe 'Hash#<<' do
it 'appends 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 'selects 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
describe 'Hash#+' do
it 'merges two hashes' do
a = { 1=>4, 2=>5, 3=>6 }
b = { 1=>4, 2=>7, 4=>0 }
(a + b).should == { 1=>4, 2=>7, 3=>6, 4=>0 }
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module HashOp
refine Hash do
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
def +(*o, &block)
merge *o, &block
end
end
end
end
|
---|
hash_zip
Summary | Adds a Hash.zip method, which makes sense. |
---|
Activate |
using SugarRefinery::HashZip
|
---|
Usage | Hash.zip
Hash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6}
|
---|
Specification | (show)
require 'sugar_refinery/hash_zip'
using SugarRefinery::HashZip
describe Hash do
describe '.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
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module HashZip
refine Hash.singleton_class do
def zip(keys, values)
Hash[ *keys.zip(values).flatten ]
end
end
end
end
|
---|
inner_map
Summary | Runs blocks on inner Array elements |
---|
Activate |
using SugarRefinery::InnerMap
|
---|
Usage | Array#inner_map
[[1, 2], [3, 4]].inner_map{ |i| i + 1 } # => [[2, 3], [4, 5]]
Array#inner_inject
[[1, 2], [3, 4]].inner_inject(&:+) # => [3, 7]
|
---|
Specification | (show)
require "sugar_refinery/inner_map"
using SugarRefinery::InnerMap
describe "Array#inner_map" do
it "should delegate map to inner lists" do
list = [[1, 2], [3, 4]]
list.inner_map { |i| i + 1 }.should == [[2, 3], [4, 5]]
end
end
describe "Array#inner_inject" do
it "should delegate inject to inner lists" do
list = [%w{a b c}, %w{d e f}]
list.inner_inject(&:+).should == list.map(&:join)
end
it "should take default values" do
list = [[3, 2, 1], [-4]]
list.inner_inject(4, &:+).should == [10, 0]
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module InnerMap
refine Array do
def inner_map(&block)
map { |object| object.map(&block) }
end
def inner_inject(default = :not_used, &block)
map { |object| default == :not_used ? object.inject(&block) : object.inject(default, &block) }
end
end
end
end
|
---|
lchomp
Summary | Adds String#chomp on the left side. |
---|
Activate |
using SugarRefinery::Lchomp
|
---|
Usage | String#lchomp
' Yes'.lchomp # => ' Yes'
String#lchomp! |
---|
Specification | (show)
require 'sugar_refinery/lchomp'
using SugarRefinery::Lchomp
describe String do
describe '#lchomp' do
it 'should chomp on the left side' do
string = 'ameise'
expect( string.lchomp('a') ).to eq 'meise'
expect( string ).to eq 'ameise'
end
end
describe '#lchomp!' do
it 'should chomp on the left side (mutating)' do
string = 'ameise'
expect( string.lchomp!('a') ).to eq 'meise'
expect( string ).to eq 'meise'
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module Lchomp
refine String do
def lchomp(arg = $/)
reverse.chomp(arg).reverse
end
def lchomp!(arg = $/)
replace reverse.chomp(arg).reverse
end
end
end
end
|
---|
marshal_copy
Summary | Adds Object#marshal_copy to create a deep copy using Marshal . |
---|
Activate |
using SugarRefinery::MarshalCopy
|
---|
Usage | Object#marshal_copy
a = %w[hello world]
b = a.marshal_copy
|
---|
Specification | (show)
require 'sugar_refinery/marshal_copy'
using SugarRefinery::MarshalCopy
describe 'Object#marshal_copy' do
it 'create a (deep) copy via marshalling' do
a = %w[hello world]
b = a.marshal_copy
b.should == a
b[0][1,1] = ''
b.should_not == a
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module MarshalCopy
refine Object do
def marshal_copy
Marshal.load Marshal.dump self
end
end
end
end
|
---|
mash
Summary | mash: map(hash) |
---|
Activate |
using SugarRefinery::Mash
|
---|
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 'sugar_refinery/mash'
using SugarRefinery::Mash
describe 'Array#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
describe 'Enumerator#mash' do
it 'should "map" a hash' do
[1,2,3].each.mash{|e| [e, e.to_s] }.should == {1=>'1',2=>'2',3=>'3',}
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module Mash
refine Enumerator do
def mash
ret = {}
each{ |kv| ret.store( *(yield(kv)[0,2]) ) }
ret
end
end
refine Array do
def mash
ret = {}
each{ |kv| ret.store( *(yield(kv)[0,2]) ) }
ret
end
end
end
end
|
---|
regexp_union
Summary | Easy creation of a Regexp.union |
---|
Activate |
using SugarRefinery::RegexpUnion
|
---|
Usage | Regexp#|, String#|
/Ruby\d/ | /test/i | "cheat"
# creates a Regexp similar to:
# /(Ruby\d|[tT][eE][sS][tT]|cheat)/
|
---|
Specification | (show)
require 'sugar_refinery/regexp_union'
using SugarRefinery::RegexpUnion
shared_examples_for "Regexp.union operator" do
it "creates a 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_relative 'version'
module SugarRefinery
module RegexpUnion
refine Regexp do
def |(arg)
Regexp.union self, arg.is_a?(Regexp) ? arg : arg.to_s
end
end
refine String do
def |(arg)
Regexp.union self, arg.is_a?(Regexp) ? arg : arg.to_s
end
end
end
end
|
---|
same
Summary | Adds Float#same? for correct number comparisons. |
---|
Activate |
using SugarRefinery::Same
|
---|
Usage | Float#same?
(0.1 + 0.2).same? 0.3 # true
|
---|
Specification | (show)
require 'sugar_refinery/same'
using SugarRefinery::Same
describe Float do
describe '#same?' do
it 'returns true if other float represents the same number' do
expect( 0.3.same?(0.1 + 0.2) ).to be true
end
end
end
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module Same
refine Float do
def same?(other)
(self - other).abs < Float::EPSILON
end
end
end
end
|
---|
string_op
Summary | More String operators. Because Strings cannot be comfortable enough! |
---|
Activate |
using SugarRefinery::StringOp
|
---|
Usage | String#-
'1234abc5678' - 'b' - /\d/ # => ac
String#^
'Yes vs No'^2 # => 's vs No'
|
---|
Specification | (show)
require 'sugar_refinery/string_op'
using SugarRefinery::StringOp
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
|
---|
Source | (show)
require_relative 'version'
module SugarRefinery
module StringOp
refine String do
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
end
end
end
|
---|
Changelog
# SUGAR REFINERY CHANGELOG
## 2016-01-03 | Sugar Refinery 1.0.0
* turn zucker gem into sugar_refinery
* move iterate into its own gem
* move instance_variable_from into its own gem
* move egonil into its own gem
* remove 'Zucker#require' and 'Zucker#require_all'
* remove 'refine' gem dependency
* remove unary_conversion in favor of https://bugs.ruby-lang.org/issues/11782
* remove square_brackets_for
* remove tap
* rename string_extras to lchomp
* rename hash_extras to hash_zip
* rename float_extras to same
* rename dir_extras to dir_utils
* split file_extras into file_force_delete and file_gsub (also remove File.filename)
## OLD ZUCKER CHANGELOG
2015-04-01 | Zucker 100.1.0
* drop Ruby 1.9 support
* add float_extras for Float#same?
* add chain_map
* add inner_map
* add array_stats
2014-04-01 | Zucker 100.0.0
* drop Ruby 1.8 support
* rewrite zucker to use refinements!
* use usual semantic versioning
* remove all "debug" cubes, use the "debugging" gem instead!
* remove "ruby_version" cube, use the "ruby_version" gem instead!
* remove "engine" cube, use the "ruby_engine" gem instead!
* remove "info" cube, use the "ruby_info" gem instead!
* remove "os" cube, use rdp's "os" gem instead!
* remove "*_to_proc" cubes, use the "procstar" gem instead!
* remove "sandbox" cube, since sandboxing is not recommended and removed from Ruby 2.1
* remove "kernel" and "not" cube completely
* tweaks to most other cubes
2013-04-30 | Zucker 13
* fix alias_for bug
* let RubyVersion#inspect and RubyEngine#inspect map to #to_s
* remove Array#sum
* repackage (gh#4)
2012-01-16 | Zucker 12
* fix a requiring bug
* rename zucker/version cube to zucker/ruby_version and Zucker::PACKAGES to Zucker::PACKS
* remove more_aliases! (keep it simple...)
* add case cube: String#to_camel and String#to_snake
2011-05-25 | Zucker 11
* add Zucker::constants to check if cube has been required (e.g. Zucker::AliasFor if 'zucker/alias_for' is loaded)
* rbx tweaks
* don't define Binding#vars on rbx (prevent endless recursion)
* sandbox-not-working warning
* add Kernel#ignore_sigquit!
* fix warnings
* doc tweaks
2011-04-29 | Zucker 10
* doc/spec tweaks
* make test.rubygems.org-testable
* fix zucker 9 permission issue
2011-01-22 | Zucker 9
* remove history versions (sorry, it caused too much gem/rdoc troubles)
* add file cube: File.delete! and File.gsub
* debug pack improvements
* binding: typos + return nil
* cc: support for ripl + return nil
* mm: also show eigenclass for modules + nicer displaying + return nil
* added Regexp#visualize
* remove optional sandbox param
* rename xxx2proc to xxx_to_proc
* change rakefile/rspec/gemspec structure
* more minor fixes and improvements
2010-10-06 | Zucker 8
* fix a little alias_for bug
* disable rdoc creation when installing (in favour of the custom docs)
* change Binding#inspect to Binding.variables (was too verbose and dangerous)
2010-10-03 | Zucker 7
* fix critical OS.windows? bug
2010-10-03 | Zucker 6
* no new cubes
* bugfix for OS.posix?
* small changes + bugfixes + doc improvements
* add two user methods to Info
* change egonil semantics ( using method_missing, see http://ruby.janlelis.de/26/catch_nil.rb )
* bugfix for vv
2010-09-04 | Zucker 5
* debug edition - add two debug helpers: oo (output line, method, file) and cc (output method callstack)
* rename cube D to dd add add more debug aliases (for mm and binding)
* fix __SPECIAL_VARS__ in info and kernel cube and some minor bugfixes
* Zucker.activate_more_aliases! option
* add Hash#&
* add aliases: File.filename (for basename), Dir.join and Dir.split (for File.join, split)
* add a flexible requiring mechansim in zucker.rb (no api changes)
* restructure packages
* add rake tasks for releasing
* improve RubyVersion constant (cleaner and more flexible)
2010-09-01 | Zucker 4
* fix Binding#inspect
* add RubyEngine constant
* add RubyVersion constant
* add OS constant
* add q debug method (like p but on one line)
* add String#-
2010-08-14 | Zucker 3
* add tap cube
* add Object#not
* add alias_for for an alternative alias syntax
* add String#constantize (improved AS version)
* improve Info module
* make Array#sum Rails compatibile
* improve docs
* change directory layout (no changes for requiring)
* more small changes
2010-08-08 | Zucker 2
* add info cube
* add chaining for array2proc
* fix Hash.zip
* fix 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