├── .gitignore
├── lib
├── sugar_refinery.rb
└── sugar_refinery
│ ├── version.rb
│ ├── all.rb
│ ├── same.rb
│ ├── marshal_copy.rb
│ ├── hash_zip.rb
│ ├── chain_map.rb
│ ├── array_op.rb
│ ├── file_force_delete.rb
│ ├── ords.rb
│ ├── lchomp.rb
│ ├── alias_for.rb
│ ├── camel_snake.rb
│ ├── regexp_union.rb
│ ├── dir_utils.rb
│ ├── inner_map.rb
│ ├── string_op.rb
│ ├── mash.rb
│ ├── file_gsub.rb
│ ├── hash_op.rb
│ ├── constantize.rb
│ ├── array_stats.rb
│ └── blank.rb
├── .rspec
├── Gemfile
├── doc
├── desc
│ ├── array_op.yaml
│ ├── same.yaml
│ ├── hash_zip.yaml
│ ├── chain_map.yaml
│ ├── dir_utils.yaml
│ ├── lchomp.yaml
│ ├── mash.yaml
│ ├── ords.yml
│ ├── marshal_copy.yaml
│ ├── string_op.yaml
│ ├── blank.yaml
│ ├── file_gsub.yaml
│ ├── regexp_union.yaml
│ ├── inner_map.yaml
│ ├── camel_snake.yaml
│ ├── file_force_delete.yaml
│ ├── hash_op.yaml
│ ├── array_stats.yaml
│ ├── alias_for.yaml
│ └── constantize.yaml
└── create_documentation.rb
├── .editorconfig
├── spec
├── same_spec.rb
├── hash_zip_spec.rb
├── marshal_copy_spec.rb
├── spec_helper.rb
├── mash_spec.rb
├── ords_spec.rb
├── array_op_spec.rb
├── camel_snake_spec.rb
├── chain_map_spec.rb
├── regexp_union_spec.rb
├── lchomp_spec.rb
├── blank_spec.rb
├── inner_map_spec.rb
├── hash_op_spec.rb
├── string_op_spec.rb
├── dir_utils_spec.rb
├── file_gsub_spec.rb
├── file_force_delete_spec.rb
├── constantize_spec.rb
├── alias_for_spec.rb
└── array_stats_spec.rb
├── .github
└── workflows
│ └── test.yml
├── sugar_refinery.gemspec
├── MIT-LICENSE.txt
├── Rakefile
├── README.md
├── CODE_OF_CONDUCT.md
└── CHANGELOG.md
/.gitignore:
--------------------------------------------------------------------------------
1 | pkg
2 | *~
3 | *.swp
4 | *.rbc
5 | Gemfile.lock
6 |
--------------------------------------------------------------------------------
/lib/sugar_refinery.rb:
--------------------------------------------------------------------------------
1 | require_relative 'sugar_refinery/version'
2 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --format documentation
3 | --require spec_helper
4 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gemspec
4 |
5 | platform :rbx do
6 | gem 'rubysl-singleton'
7 | end
8 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module SugarRefinery
4 | VERSION = '1.0.1'
5 | end
6 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/all.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | Dir["#{File.dirname(__FILE__)}/*"].each{ |f|
4 | require_relative File.basename(f)
5 | }
6 |
--------------------------------------------------------------------------------
/doc/desc/array_op.yaml:
--------------------------------------------------------------------------------
1 | array_op:
2 | summary: Operators one could miss for ⇧Array⇧
3 | methods:
4 | Array#^: "[1,2,3,4] ^ [3,4,5,6] # => [1,2,5,6]"
5 |
--------------------------------------------------------------------------------
/doc/desc/same.yaml:
--------------------------------------------------------------------------------
1 | same:
2 | summary: "Adds ⇧Float#same?⇧ for correct number comparisons."
3 | methods:
4 | Float#same?: "(0.1 + 0.2).same? 0.3 # true"
5 |
--------------------------------------------------------------------------------
/doc/desc/hash_zip.yaml:
--------------------------------------------------------------------------------
1 | hash_zip:
2 | summary: "Adds a ⇧Hash.zip⇧ method, which makes sense."
3 | methods:
4 | Hash.zip: "Hash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6}"
5 |
--------------------------------------------------------------------------------
/doc/desc/chain_map.yaml:
--------------------------------------------------------------------------------
1 | chain_map:
2 | summary: Chain multiple procs on ⇧Array⇧ elements
3 | methods:
4 | Array#chain_map: '[-3, -2, -1].chain_map(:abs, :to_s) # => ["3", "2", "1"]'
5 |
--------------------------------------------------------------------------------
/doc/desc/dir_utils.yaml:
--------------------------------------------------------------------------------
1 | dir_utils:
2 | summary: Some shortcuts for working with directories
3 | methods:
4 | Dir.join: File.join
5 | Dir.split: File.split
6 | Dir.rm: FileUtils.rm_r
7 |
8 |
--------------------------------------------------------------------------------
/doc/desc/lchomp.yaml:
--------------------------------------------------------------------------------
1 | lchomp:
2 | summary: "Adds ⇧String#chomp⇧ on the left side."
3 | methods:
4 | String#lchomp: "' Yes'.lchomp # => ' Yes'"
5 | String#lchomp!: "# mutable lchomp version"
6 |
--------------------------------------------------------------------------------
/doc/desc/mash.yaml:
--------------------------------------------------------------------------------
1 | mash:
2 | summary: "mash: map(hash)"
3 | methods:
4 | Enumerable#mash: "[1,2,3].mash{|e| [e, e.to_s] } # => {1=>'1',2=>'2',3=>'3'}"
5 | info:
6 | - Inspired by Ruby Facets' ⇧mash⇧.
7 |
8 |
--------------------------------------------------------------------------------
/doc/desc/ords.yml:
--------------------------------------------------------------------------------
1 | ords:
2 | summary: Easy way to pack and unpack your characters
3 | methods:
4 | Array#chrs: "[72, 97, 108, 108, 111].chrs # => 'Hallo'"
5 | String#ords: "'Hallo'.ords # => [72, 97, 108, 108, 111]"
--------------------------------------------------------------------------------
/doc/desc/marshal_copy.yaml:
--------------------------------------------------------------------------------
1 | marshal_copy:
2 | summary: Adds ⇧Object#marshal_copy⇧ to create a deep copy using ⇧Marshal⇧.
3 | methods:
4 | Object#marshal_copy: |
5 | a = %w[hello world]
6 | b = a.marshal_copy
7 |
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [*.{md,rdoc,txt}]
11 | indent_size = 4
12 |
13 |
--------------------------------------------------------------------------------
/doc/desc/string_op.yaml:
--------------------------------------------------------------------------------
1 | string_op:
2 | summary: "More ⇧String⇧ operators. Because Strings cannot be comfortable enough!"
3 | methods:
4 | String#-: "'1234abc5678' - 'b' - /\\d/ # => ac"
5 | String#^: "'Yes vs No'^2 # => 's vs No'"
6 |
--------------------------------------------------------------------------------
/doc/desc/blank.yaml:
--------------------------------------------------------------------------------
1 | blank:
2 | summary: "Does pretty the same as in ActiveSupport: Every object can be asked if it is blank or present"
3 | methods:
4 | Object#blank?: |
5 | 'an object'.blank? # => false
6 | nil.present? # => false
7 |
8 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/same.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Same
5 | refine Float do
6 | def same?(other)
7 | (self - other).abs < Float::EPSILON
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/doc/desc/file_gsub.yaml:
--------------------------------------------------------------------------------
1 | file_gsub:
2 | summary: Will read the file and substitute the hash keys with their values
3 | methods:
4 | File.gsub: |
5 | File.gsub 'some_filename',
6 | /hi/ => 'cu',
7 | /\d/ => proc{ |m| (m.to_i+1).to_s }
8 |
9 |
--------------------------------------------------------------------------------
/doc/desc/regexp_union.yaml:
--------------------------------------------------------------------------------
1 | regexp_union:
2 | summary: Easy creation of a ⇧Regexp.union⇧
3 | methods:
4 | Regexp#|, String#|: |
5 | /Ruby\d/ | /test/i | "cheat"
6 | # creates a Regexp similar to:
7 | # /(Ruby\d|[tT][eE][sS][tT]|cheat)/
8 |
9 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/marshal_copy.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module MarshalCopy
5 | refine Object do
6 | def marshal_copy
7 | Marshal.load Marshal.dump self
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/doc/desc/inner_map.yaml:
--------------------------------------------------------------------------------
1 | inner_map:
2 | summary: Runs blocks on inner ⇧Array⇧ elements
3 | methods:
4 | Array#inner_map: "[[1, 2], [3, 4]].inner_map{ |i| i + 1 } # => [[2, 3], [4, 5]]"
5 | Array#inner_inject: "[[1, 2], [3, 4]].inner_inject(&:+) # => [3, 7]"
6 |
--------------------------------------------------------------------------------
/doc/desc/camel_snake.yaml:
--------------------------------------------------------------------------------
1 | camel_snake:
2 | summary: Provides ⇧String#to_camel⇧ and ⇧String#to_snake⇧.
3 | methods:
4 | String#to_camel: "'was_snake_string'.to_camel # => 'WasSnakeString'"
5 | String#to_snake: "'WasCamelString'.to_snake # => 'was_camel_string'"
6 |
7 |
--------------------------------------------------------------------------------
/doc/desc/file_force_delete.yaml:
--------------------------------------------------------------------------------
1 | file_force_delete:
2 | summary: ⇧File.delete!⇧ (like `rm -f`)
3 | methods:
4 | File.delete!: "File.delete! 'some_filename' # will delete the file, don't care if it exist."
5 | info:
6 | - "Idea for ⇧File.delete!⇧ from sugar-high."
7 |
8 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/hash_zip.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module HashZip
5 | refine Hash.singleton_class do
6 | def zip(keys, values)
7 | Hash[ *keys.zip(values).flatten ]
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/same_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/same'
2 | using SugarRefinery::Same
3 |
4 | describe Float do
5 | describe '#same?' do
6 | it 'returns true if other float represents the same number' do
7 | expect( 0.3.same?(0.1 + 0.2) ).to be true
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/chain_map.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module ChainMap
5 | refine Array do
6 | def chain_map(*args)
7 | args.inject(self) { |collection, action| collection.map(&action) }
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/array_op.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module ArrayOp
5 | refine Array do
6 | def ^(other)
7 | (self - other) + (other - self)
8 | end
9 |
10 | def **(*o, &block)
11 | product *o, &block
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/file_force_delete.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module FileForceDelete
5 | refine File.singleton_class do
6 | def delete!(filename)
7 | return nil if !File.exist?(filename)
8 | File.delete filename
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/ords.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Ords
5 | refine Array do
6 | def chrs
7 | self.pack 'C*'
8 | end
9 | end
10 |
11 | refine String do
12 | def ords
13 | self.unpack 'C*'
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/lchomp.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Lchomp
5 | refine String do
6 | def lchomp(arg = $/)
7 | reverse.chomp(arg).reverse
8 | end
9 |
10 | def lchomp!(arg = $/)
11 | replace reverse.chomp(arg).reverse
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/hash_zip_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/hash_zip'
2 | using SugarRefinery::HashZip
3 |
4 |
5 | describe Hash do
6 | describe '.zip' do
7 | it 'should zip together both given enumerables and take them as key=>values for a new hash' do
8 | Hash.zip( [1,2,3], [4,5,6] ).should == { 1=>4, 2=>5, 3=>6 }
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/doc/desc/hash_op.yaml:
--------------------------------------------------------------------------------
1 | hash_op:
2 | summary: Sugar for dealing with hashes
3 | methods:
4 | Hash#<<: |
5 | {1=>2} << [3, 4] # => { 1=>2, 3=>4 }
6 | {1=>2} << { 5=>6 } # => { 1=>2, 5=>6 }
7 | Hash#&: "{ 1=>4, 2=>5, 3=>6 } & { 1=>4, 2=>7 } # => { 1=>4 }"
8 | info:
9 | - Some of the operators are inspired by Ruby Facets.
10 |
11 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/alias_for.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module AliasFor
5 | refine Module do
6 | private
7 |
8 | def alias_for(m, *aliases)
9 | aliases.each{ |a| class_eval "alias :'#{ a }' :'#{ m }'" }
10 | end
11 |
12 | alias aliases_for alias_for
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/marshal_copy_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/marshal_copy'
2 | using SugarRefinery::MarshalCopy
3 |
4 |
5 | describe 'Object#marshal_copy' do
6 | it 'create a (deep) copy via marshalling' do
7 | a = %w[hello world]
8 | b = a.marshal_copy
9 | b.should == a
10 |
11 | b[0][1,1] = ''
12 | b.should_not == a
13 | end
14 | end
15 |
16 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/camel_snake.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module CamelSnake
5 | refine String do
6 | def to_snake
7 | gsub(/(?'1',2=>'2',3=>'3',}
8 | end
9 | end
10 |
11 |
12 | describe 'Enumerator#mash' do
13 | it 'should "map" a hash' do
14 | [1,2,3].each.mash{|e| [e, e.to_s] }.should == {1=>'1',2=>'2',3=>'3',}
15 | end
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/spec/ords_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/ords'
2 | using SugarRefinery::Ords
3 |
4 |
5 | describe 'Array#chrs' do
6 | it 'converts the array to a string, using each element as ord value for the char' do
7 | [72, 97, 108, 108, 111].chrs.should == 'Hallo'
8 | end
9 | end
10 |
11 | describe 'String#ords' do
12 | it 'unpacks characters' do
13 | 'Hallo'.ords.should == [72, 97, 108, 108, 111]
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/array_op_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/array_op'
2 | using SugarRefinery::ArrayOp
3 |
4 |
5 | describe 'Array#^' do
6 | it 'does an exclusive or' do
7 | a = [1,2,3,4]
8 | b = [3,4,5,6]
9 | (a^b).should == [1,2,5,6]
10 | end
11 | end
12 |
13 | describe 'Array#**' do
14 | it 'returns the array product' do
15 | ([1,2] ** %w[a b]).should == [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/dir_utils.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 | require 'fileutils'
3 |
4 | module SugarRefinery
5 | module DirUtils
6 | refine Dir.singleton_class do
7 | def join(*args)
8 | File.join(*args)
9 | end
10 |
11 | def split(*args)
12 | File.split(*args)
13 | end
14 |
15 | def rm(*args)
16 | FileUtils.rm_r(*args)
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/inner_map.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module InnerMap
5 | refine Array do
6 | def inner_map(&block)
7 | map { |object| object.map(&block) }
8 | end
9 |
10 | def inner_inject(default = :not_used, &block)
11 | map { |object| default == :not_used ? object.inject(&block) : object.inject(default, &block) }
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/string_op.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module StringOp
5 | refine String do
6 | def -(rem)
7 | gsub( Regexp === rem ? rem : rem.to_s, '' )
8 | end
9 |
10 | def ^(pos)
11 | pos = pos.to_i
12 | if pos >= 0
13 | self[pos..-1]
14 | else
15 | self[0...pos]
16 | end
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/spec/camel_snake_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/camel_snake'
2 | using SugarRefinery::CamelSnake
3 |
4 |
5 | describe 'String#to_camel' do
6 | it 'should turn a snake_cased string to CamelCase' do
7 | 'was_snake_case'.to_camel.should == 'WasSnakeCase'
8 | end
9 | end
10 |
11 | describe 'String#to_snake' do
12 | it 'should turn a CamelCased string to snake_case' do
13 | 'WasCamelCase'.to_snake.should == 'was_camel_case'
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/mash.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Mash
5 | refine Enumerator do
6 | def mash
7 | ret = {}
8 | each{ |kv| ret.store( *(yield(kv)[0,2]) ) }
9 | ret
10 | end
11 | end
12 |
13 | refine Array do
14 | def mash
15 | ret = {}
16 | each{ |kv| ret.store( *(yield(kv)[0,2]) ) }
17 | ret
18 | end
19 | end
20 | end
21 | end
22 |
23 |
--------------------------------------------------------------------------------
/spec/chain_map_spec.rb:
--------------------------------------------------------------------------------
1 | require "sugar_refinery/chain_map"
2 | using SugarRefinery::ChainMap
3 |
4 | describe "Array#chain_map" do
5 | it "should repeatedly chain symbols as map calls" do
6 | list = [-3, -2, -1]
7 |
8 | list.chain_map(:abs, :to_s) == %w{3 2 1}
9 | end
10 |
11 | it "should repeatedly chain blocks as map calls" do
12 | list = [-3, -2, -1]
13 |
14 | list.chain_map(->(e) { e ** 2 }, ->(e) { e * -1 }) == [-9, -4, -1]
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/doc/desc/alias_for.yaml:
--------------------------------------------------------------------------------
1 | alias_for:
2 | summary: 'A different way to create aliases: Reversed order and you can pass multiple alias names. The order feels more logical'
3 | methods:
4 | Module#alias_for, Module#aliases_for: |
5 | # creates an alias for the method :methods with the name ms
6 | class Object
7 | alias_for :methods, :ms
8 | end
9 |
10 | # creates multiple aliases
11 | module Enumerable
12 | aliases_for :zip, :with, :%
13 | end
14 |
--------------------------------------------------------------------------------
/spec/regexp_union_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/regexp_union'
2 | using SugarRefinery::RegexpUnion
3 |
4 |
5 | shared_examples_for "Regexp.union operator" do
6 | it "creates a Regexp.union of both operands" do
7 | (/Ruby\d/ | /test/i | "cheat").should ==
8 | Regexp.union( Regexp.union( /Ruby\d/, /test/i ), "cheat" )
9 | end
10 | end
11 |
12 | describe 'Regexp#|' do
13 | it_should_behave_like 'Regexp.union operator'
14 | end
15 |
16 | describe 'String#|' do
17 | it_should_behave_like 'Regexp.union operator'
18 | end
19 |
20 |
--------------------------------------------------------------------------------
/spec/lchomp_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/lchomp'
2 | using SugarRefinery::Lchomp
3 |
4 | describe String do
5 | describe '#lchomp' do
6 | it 'should chomp on the left side' do
7 | string = 'ameise'
8 | expect( string.lchomp('a') ).to eq 'meise'
9 | expect( string ).to eq 'ameise'
10 | end
11 | end
12 |
13 | describe '#lchomp!' do
14 | it 'should chomp on the left side (mutating)' do
15 | string = 'ameise'
16 | expect( string.lchomp!('a') ).to eq 'meise'
17 | expect( string ).to eq 'meise'
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/doc/desc/constantize.yaml:
--------------------------------------------------------------------------------
1 | constantize:
2 | summary: "Easier handling of dynamic constant names"
3 | methods:
4 | String#constantize: |
5 | 'Object'.constantize # => Object
6 | 'Spec::VERSION'.constantize # => Spec::VERSION if rspec is loaded
7 | # you can also pass a parameter or block to define what happens, when constant does not exist
8 | 'IdontExist'.constantize(Array) # => Array
9 | 'String5'.constantize do |string|
10 | string.chop.constantize
11 | end # => String
12 | info:
13 | - "An improved version of ActiveSupport's one"
14 |
15 |
--------------------------------------------------------------------------------
/spec/blank_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/blank'
2 | using SugarRefinery::Blank
3 |
4 |
5 | describe 'Object#blank?' do
6 | it 'should be blank for blank values' do
7 | blank_values = [ nil, false, '', ' ', " \n\t \r ", [], {}, // ]
8 |
9 | blank_values.each{ |blank|
10 | blank.blank?.should == true
11 | }
12 | end
13 |
14 | it 'should not be blank for non blank values' do
15 | present_values = [ Object.new, true, 0, 1, 'a', [nil], { nil => nil } ]
16 |
17 | present_values.each{ |present|
18 | present.blank?.should == false
19 | }
20 | end
21 | end
22 |
23 |
--------------------------------------------------------------------------------
/spec/inner_map_spec.rb:
--------------------------------------------------------------------------------
1 | require "sugar_refinery/inner_map"
2 | using SugarRefinery::InnerMap
3 |
4 | describe "Array#inner_map" do
5 | it "should delegate map to inner lists" do
6 | list = [[1, 2], [3, 4]]
7 |
8 | list.inner_map { |i| i + 1 }.should == [[2, 3], [4, 5]]
9 | end
10 | end
11 |
12 | describe "Array#inner_inject" do
13 | it "should delegate inject to inner lists" do
14 | list = [%w{a b c}, %w{d e f}]
15 |
16 | list.inner_inject(&:+).should == list.map(&:join)
17 | end
18 |
19 | it "should take default values" do
20 | list = [[3, 2, 1], [-4]]
21 |
22 | list.inner_inject(4, &:+).should == [10, 0]
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/file_gsub.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module FileGsub
5 | refine File.singleton_class do
6 | def gsub(filename, regex_hash)
7 | data = File.read filename
8 | File.open(filename,'w'){ |file|
9 | regex_hash.each{ |regex, new_string|
10 | regex = regex.to_s unless regex.is_a? Regexp
11 |
12 | if new_string.is_a? Proc
13 | data.gsub! regex, &new_string
14 | else
15 | data.gsub! regex, new_string
16 | end
17 | }
18 | file.print data
19 | }
20 | end
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | name: Ruby ${{ matrix.ruby }} (${{ matrix.os }})
8 | if: "!contains(github.event.head_commit.message, '[skip ci]')"
9 | strategy:
10 | matrix:
11 | ruby:
12 | - 3.0
13 | - 2.7
14 | - 2.6
15 | - 2.5
16 | os:
17 | - ubuntu-latest
18 | runs-on: ${{matrix.os}}
19 | steps:
20 | - uses: actions/checkout@v2
21 | - name: Set up Ruby
22 | uses: ruby/setup-ruby@v1
23 | with:
24 | ruby-version: ${{matrix.ruby}}
25 | bundler-cache: true
26 | - name: Run tests
27 | run: bundle exec rake
28 |
--------------------------------------------------------------------------------
/spec/hash_op_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/hash_op'
2 | using SugarRefinery::HashOp
3 |
4 |
5 | describe 'Hash#<<' do
6 | it 'appends new elements to the hash' do
7 | a = { 1=>4, 2=>5, 3=>6 }
8 | a << { 4=>7 }
9 | a << [5, 8]
10 | a.should == { 1=>4, 2=>5, 3=>6, 4=>7, 5=>8 }
11 | end
12 | end
13 |
14 | describe 'Hash#&' do
15 | it 'selects a sub hash containt only equal key-value pairs' do
16 | a = { 1=>4, 2=>5, 3=>6 }
17 | b = { 1=>4, 2=>7 }
18 | (a & b).should == { 1=>4 }
19 | end
20 | end
21 |
22 | describe 'Hash#+' do
23 | it 'merges two hashes' do
24 | a = { 1=>4, 2=>5, 3=>6 }
25 | b = { 1=>4, 2=>7, 4=>0 }
26 | (a + b).should == { 1=>4, 2=>7, 3=>6, 4=>0 }
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/hash_op.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module HashOp
5 | refine Hash do
6 | def <<(other)
7 | case
8 | when other.is_a?(Hash)
9 | merge! other
10 | when other.is_a?(Enumerable) || other.respond_to?(:to_splat)
11 | merge! Hash[*other]
12 | else
13 | raise TypeError, 'can only append other Hashs and Enumerables (or Classes that implement to_splat)'
14 | end
15 | end
16 |
17 | def &(other)
18 | Hash[ *select{ |k,v|
19 | other[k] == v
20 | }.flatten ]
21 | end
22 |
23 | def +(*o, &block)
24 | merge *o, &block
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/string_op_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/string_op'
2 | using SugarRefinery::StringOp
3 |
4 |
5 | describe 'String#-' do
6 | it 'should remove the applied Regexp or String from self via gsub' do
7 | ('1234abc5678' - 'b' - /\d/).should == 'ac'
8 | end
9 | end
10 |
11 | describe 'String#^' do
12 | it 'should give C-like substring access to strings' do
13 | string = 'Theoretische Informatik ist voll geil!'
14 |
15 | (string^0).should == 'Theoretische Informatik ist voll geil!'
16 | (string^1).should == 'heoretische Informatik ist voll geil!'
17 | (string^13).should == 'Informatik ist voll geil!'
18 | (string^-1).should == 'Theoretische Informatik ist voll geil'
19 | (string^38).should == ''
20 | (string^99).should == nil
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/constantize.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Constantize
5 | refine String do
6 | def constantize(default_value = nil) # always uses global scope as in AS... is this good?
7 | get_constant = lambda{
8 | self.split(/::/).inject( Object ){ |base_constant, current_constant|
9 | base_constant.const_get current_constant
10 | }
11 | }
12 |
13 | if !default_value && !block_given?
14 | get_constant.call
15 | else
16 | begin
17 | get_constant.call
18 | rescue NameError
19 | if block_given?
20 | yield self
21 | else
22 | default_value
23 | end
24 | end
25 | end
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/spec/dir_utils_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/dir_utils'
2 | require 'securerandom'
3 | using SugarRefinery::DirUtils
4 |
5 |
6 | describe Dir do
7 | describe '.join' do
8 | it 'delegates to File.join' do
9 | a = %w[some file path]
10 | expect( Dir.join(a) ).to be == File.join(a)
11 | end
12 | end
13 |
14 | describe '.split' do
15 | it 'delegates to File.split' do
16 | a = 'some/file/path'
17 | expect( Dir.split(a) ).to be == File.split(a)
18 | end
19 | end
20 |
21 | describe '.rm' do
22 | it 'removes directories with content' do
23 | path = "tmp_#{SecureRandom.uuid}"
24 | FileUtils.mkdir path
25 | FileUtils.touch "#{path}/123"
26 | expect{
27 | Dir.rm path
28 | }.not_to raise_error
29 | expect( Dir['*'] ).to_not include(path)
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/array_stats.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module ArrayStats
5 | refine Array do
6 | def mean
7 | inject(&:+) / length.to_f
8 | end
9 |
10 | def stdev(type = :population)
11 | case type
12 | when :population then stdev_population
13 | when :sample then stdev_sample
14 | else raise ArgumentError.new("%s is not a valid argument" % type)
15 | end
16 | end
17 |
18 | def stdev_sample
19 | Math.sqrt(inject(0.0) { |sum, x| sum + (mean - x) ** 2 } / (length - 1))
20 | end
21 |
22 | def stdev_population
23 | Math.sqrt(inject(0.0) { |sum, x| sum + (mean - x) ** 2 } / length)
24 | end
25 |
26 | def z_score(type = :population)
27 | map { |x| (x - mean) / stdev(type) }
28 | end
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/spec/file_gsub_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/file_gsub'
2 | require 'fileutils'
3 | using SugarRefinery::FileGsub
4 |
5 |
6 | describe File do
7 | describe '.gsub' do
8 | let :random_filename do
9 | 'test_' + (0..20).map{|e| [*'a'..'z'].sample }*''
10 | end
11 |
12 | it 'should read filename in arg1, substitute every key in the arg2 with its value and save the file' do
13 | File.open(random_filename,'w'){ |file|
14 | file.print 'should read filename in arg1, substitute every key in the arg2 with its value and save the file'
15 | }
16 | File.gsub random_filename,
17 | /read/ => 'write',
18 | /\d+/ => proc{|m| (m.to_i+1).to_s }
19 |
20 | File.read(random_filename).should ==
21 | 'should write filename in arg2, substitute every key in the arg3 with its value and save the file'
22 |
23 | FileUtils.rm random_filename
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/lib/sugar_refinery/blank.rb:
--------------------------------------------------------------------------------
1 | require_relative 'version'
2 |
3 | module SugarRefinery
4 | module Blank
5 | refine Object do
6 | def blank?
7 | if respond_to? :empty? then empty? else !self end
8 | end
9 |
10 | def present?
11 | !blank?
12 | end
13 | end
14 |
15 | refine NilClass do
16 | def blank?() true end
17 | end
18 |
19 | refine FalseClass do
20 | def blank?() true end
21 | end
22 |
23 | refine TrueClass do
24 | def blank?() false end
25 | end
26 |
27 | refine Numeric do
28 | def blank?() false end
29 | end
30 |
31 | refine Array do
32 | def blank?() empty? end
33 | end
34 |
35 | refine Hash do
36 | def blank?() empty? end
37 | end
38 |
39 | refine String do
40 | def blank?() self !~ /\S/ end
41 | end
42 |
43 | refine Regexp do
44 | def blank?() self == // end
45 | end
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/spec/file_force_delete_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/file_force_delete'
2 | require 'fileutils'
3 | using SugarRefinery::FileForceDelete
4 |
5 |
6 | describe File do
7 | describe '.delete!' do
8 | after{ File.delete! 'random_filename' }
9 | let :random_filename do
10 | 'test_' + (0..20).map{|e| [*'a'..'z'].sample }*''
11 | end
12 |
13 | it 'should delete the filename given as argument if it exists + return non-nil' do
14 | FileUtils.touch random_filename
15 | res = false
16 | proc do
17 | res = File.delete! random_filename
18 | end.should_not raise_exception
19 | res.should be_truthy
20 | end
21 |
22 | it 'should do nothing if the filename given as argument does not exist + return nil' do
23 | res = false
24 | proc do
25 | res = File.delete! random_filename
26 | end.should_not raise_exception
27 | res.should be_falsey
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/sugar_refinery.gemspec:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | require File.dirname(__FILE__) + '/lib/sugar_refinery/version'
3 |
4 | Gem::Specification.new do |s|
5 | s.name = "sugar_refinery"
6 | s.version = SugarRefinery::VERSION
7 | s.authors = ['Jan Lelis']
8 | s.email = ['hi@ruby.consulting']
9 | s.summary = "The Ruby Sugar Refinery is a collection of tiny refinements."
10 | s.description = "The Ruby Sugar Refinery is a collection of tiny refinements (declarative local core extensions)."
11 | s.homepage = "https://janlelis.github.io/sugar_refinery"
12 | s.files = Dir.glob( %w[{lib,spec}/**/*.rb desc/**/*.yaml] ) + %w{Rakefile sugar_refinery.gemspec MIT-LICENSE.txt README.md CHANGELOG.md doc/create_documentation.rb doc/index.html}
13 | s.require_paths = ["lib"]
14 | s.license = 'MIT'
15 |
16 | s.required_ruby_version = '>= 2.0'
17 | s.add_development_dependency 'rake', '~> 13.0'
18 | s.add_development_dependency 'rspec', '~> 2.99'
19 | s.add_development_dependency 'coderay', '~> 1.1'
20 | end
21 |
--------------------------------------------------------------------------------
/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2016 Jan Lelis
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # # #
2 | # Get gemspec info
3 |
4 | gemspec_file = Dir['*.gemspec'].first
5 | gemspec = eval File.read(gemspec_file), binding, gemspec_file
6 | info = "#{gemspec.name} | #{gemspec.version} | " \
7 | "#{gemspec.runtime_dependencies.size} dependencies | " \
8 | "#{gemspec.files.size} files"
9 |
10 |
11 | # # #
12 | # Gem build and install task
13 |
14 | desc info
15 | task :gem do
16 | puts info + "\n\n"
17 | print " "; sh "gem build #{gemspec_file}"
18 | FileUtils.mkdir_p 'pkg'
19 | FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
20 | puts; sh %{gem install --no-document pkg/#{gemspec.name}-#{gemspec.version}.gem}
21 | end
22 |
23 |
24 | # # #
25 | # Start an IRB session with the gem loaded
26 |
27 | desc "#{gemspec.name} | IRB"
28 | task :irb do
29 | sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}"
30 | end
31 |
32 |
33 | # # #
34 | # Run Specs
35 |
36 | desc "#{gemspec.name} | Spec"
37 | task 'spec' do
38 | sh %[rspec spec]
39 | end
40 | task default: :spec
41 |
42 |
43 | # # #
44 | # Documentation
45 |
46 | desc "#{gemspec.name} | Documentation"
47 | task 'doc' do
48 | ruby 'doc/create_documentation.rb'
49 | end
50 |
--------------------------------------------------------------------------------
/spec/constantize_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/constantize'
2 | using SugarRefinery::Constantize
3 |
4 |
5 | describe 'String#constantize' do
6 | it 'should return the constant with that name' do
7 | 'Object'.constantize.should == Object
8 | end
9 |
10 | it 'should also work for nested constants' do
11 | 'SugarRefinery::VERSION'.constantize.should == SugarRefinery::VERSION
12 | end
13 |
14 | it 'should throw name error if constant does not exist (and no parameter is given)' do
15 | proc do
16 | 'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.constantize
17 | end.should raise_exception NameError
18 | end
19 |
20 | it 'should call the block (and not raise an error) if constant does not exist and block given' do
21 | proc do
22 | 'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.constantize do |string|
23 | Default = [1,2,3]
24 | end.should == [1,2,3]
25 | end.should_not raise_exception
26 | end
27 |
28 | it 'should return the second parameter (and not raise an error) if constant does not exist and parameter given' do
29 | proc do
30 | 'ObfsefsefsefafesafaefRubySugarRefineryafdfselijfesject'.constantize(Array).should == Array
31 | end.should_not raise_exception
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/spec/alias_for_spec.rb:
--------------------------------------------------------------------------------
1 | require 'sugar_refinery/alias_for'
2 | using SugarRefinery::AliasFor
3 |
4 |
5 | describe 'alias_for' do
6 | it 'should create an alias for instance methods' do
7 | class Array
8 | def m2
9 | 2
10 | end
11 | aliases_for :m2, :a2, :'a-2'
12 | end
13 | proc do
14 | [1,2,3].a2.should == 2
15 | [1,2,3].send('a-2').should == 2
16 | end.should_not raise_exception
17 | end
18 |
19 | it 'should create an alias for class (singleton) methods' do
20 | class Array
21 | class << Array
22 | def m3
23 | 3
24 | end
25 | alias_for :m3, :a3
26 | end
27 | end
28 |
29 | proc{
30 | Array.a3.should == 3
31 | }.should_not raise_exception
32 | end
33 |
34 |
35 | it 'should create aliases for the first argument with all other arguments' do
36 | class Object
37 | def m4
38 | 4
39 | end
40 | alias_for :m4, :ma, :mb, :mc
41 | end
42 |
43 | proc{
44 | 1.ma.should == 4
45 | "1".mb.should == 4
46 | [1].mc.should == 4
47 | }.should_not raise_exception
48 | end
49 |
50 | it 'works with uncommon chars' do
51 | class Object
52 | alias_for :tainted?, :"tain-ted?"
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ruby Sugar Refinery [](https://badge.fury.io/rb/sugar_refinery) [![[ci]](https://github.com/janlelis/sugar_refinery/workflows/Test/badge.svg)](https://github.com/janlelis/sugar_refinery/actions?query=workflow%3ATest)
2 |
3 | The Ruby Sugar Refinery is a collection of tiny [refinements](https://ruby-doc.org/core/doc/syntax/refinements_rdoc.html) (declarative local core extensions) for Ruby.
4 |
5 | ## Setup & usage
6 |
7 | Add to Gemfile:
8 |
9 | ```ruby
10 | gem 'sugar_refinery', require: 'sugar_refinery/all'
11 | ```
12 |
13 | Then add refinements to the current Ruby file or module:
14 |
15 | ```ruby
16 | using SugarRefinery::CamelSnake
17 | using SugarRefinery::HashZip
18 |
19 | "ClassName".to_snake # => "class_name"
20 | Hash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6}
21 | ```
22 |
23 | ## List of included refinements
24 |
25 | Please see [the documentation](http://janlelis.github.io/sugar_refinery), [the code](https://github.com/janlelis/sugar_refinery/tree/master/lib/sugar_refinery) or [the specs](https://github.com/janlelis/sugar_refinery/tree/master/spec)!
26 |
27 | ## The Sugar Refinery was Zucker before
28 |
29 | This collection of core extensions used to be called **zucker**.
30 |
31 | Missing former functionality? It might have been extracted into a separate micro gem:
32 |
33 | * [iterate](https://github.com/janlelis/iterate) | Control structure-like iteration
34 | * [instance_variables_from](https://github.com/janlelis/instance_variables_from) | Auto-assign instance variables
35 | * [egonil](https://github.com/janlelis/egonil) | Egocentric nil
36 | * [debugging](https://github.com/janlelis/debugging) | Print debugging helpers
37 | * [procstar](https://github.com/janlelis/procstar) | Beyond symbol2proc
38 | * [ruby_info](https://github.com/janlelis/ruby_info) | Misc information about the Ruby environment
39 | * [ruby_version](https://github.com/janlelis/ruby_version) | Smart Ruby version accessor
40 | * [ruby_engine](https://github.com/janlelis/ruby_engine) | Smar Ruby engine accessor
41 |
42 | ## J-_-L
43 |
44 | Copyright (c) 2010-2016 [Jan Lelis](https://janlelis.com), released under the MIT license
45 |
--------------------------------------------------------------------------------
/spec/array_stats_spec.rb:
--------------------------------------------------------------------------------
1 | require "sugar_refinery/array_stats"
2 | using SugarRefinery::ArrayStats
3 |
4 | describe "doing statistics on arrays" do
5 | let(:list) { (2..5).to_a }
6 |
7 | describe "Array#mean" do
8 | it "should return the average" do
9 | list.mean.should == 3.5
10 | end
11 | end
12 |
13 | describe "Array#stdev_sample" do
14 | it "should return the standard deviation of the sample" do
15 | list.stdev_sample.should be_within(1e-8).of(1.2909944487358056)
16 | end
17 | end
18 |
19 | describe "Array#stdev_population" do
20 | it "should return the standard deviation of the population" do
21 | list.stdev_population.should be_within(1e-8).of(1.118033988749895)
22 | end
23 | end
24 |
25 | describe "Array#stdev" do
26 | it "should default to population" do
27 | list.stdev.should be_within(1e-8).of(list.stdev_population)
28 | end
29 |
30 | it "should delegate sample correctly" do
31 | list.stdev(:sample).should be_within(1e-8).of(list.stdev_sample)
32 | end
33 |
34 | it "should delegate population correctly" do
35 | list.stdev(:population).should be_within(1e-8).of(list.stdev_population)
36 | end
37 |
38 | it "should raise an error with any other key" do
39 | expect { list.stdev(:pony) }.to raise_error(ArgumentError)
40 | end
41 | end
42 |
43 | describe "Array#z_score" do
44 | it "should default to population" do
45 | list.z_score.zip(list.z_score(:population)).each do |value, actual|
46 | value.should be_within(1e-8).of(actual)
47 | end
48 | end
49 |
50 | it "should delegate sample correctly" do
51 | sample_z_score = [
52 | -1.161895003862225,
53 | -0.3872983346207417,
54 | 0.3872983346207417,
55 | 1.161895003862225
56 | ]
57 |
58 | p list
59 |
60 | list.z_score(:sample).zip(sample_z_score).each do |value, actual|
61 | value.should be_within(1e-8).of(actual)
62 | end
63 | end
64 |
65 | it "should delegate population correctly" do
66 | population_z_score = [
67 | -1.3416407864998738,
68 | -0.4472135954999579,
69 | 0.4472135954999579,
70 | 1.3416407864998738
71 | ]
72 |
73 | list.z_score(:population).zip(population_z_score).each do |value, actual|
74 | value.should be_within(1e-8).of(actual)
75 | end
76 | end
77 |
78 | it "should raise an error with any other key" do
79 | expect { list.z_score(:pony) }.to raise_error(ArgumentError)
80 | end
81 | end
82 | end
83 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at conduct@janlelis.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # SUGAR REFINERY CHANGELOG
2 |
3 | ## 2021-01-07 | Sugar Refinery 1.0.1
4 |
5 | * Relax Ruby version requirement to allow Ruby 3.0
6 |
7 |
8 | ## 2016-01-03 | Sugar Refinery 1.0.0
9 |
10 | * turn zucker gem into sugar_refinery
11 | * move iterate into its own gem
12 | * move instance_variable_from into its own gem
13 | * move egonil into its own gem
14 | * remove 'Zucker#require' and 'Zucker#require_all'
15 | * remove 'refine' gem dependency
16 | * remove unary_conversion in favor of https://bugs.ruby-lang.org/issues/11782
17 | * remove square_brackets_for
18 | * remove tap
19 | * rename string_extras to lchomp
20 | * rename hash_extras to hash_zip
21 | * rename float_extras to same
22 | * rename dir_extras to dir_utils
23 | * split file_extras into file_force_delete and file_gsub (also remove File.filename)
24 |
25 |
26 | ## OLD ZUCKER CHANGELOG
27 |
28 | 2015-04-01 | Zucker 100.1.0
29 | * drop Ruby 1.9 support
30 | * add float_extras for Float#same?
31 | * add chain_map
32 | * add inner_map
33 | * add array_stats
34 |
35 |
36 | 2014-04-01 | Zucker 100.0.0
37 | * drop Ruby 1.8 support
38 | * rewrite zucker to use refinements!
39 | * use usual semantic versioning
40 | * remove all "debug" cubes, use the "debugging" gem instead!
41 | * remove "ruby_version" cube, use the "ruby_version" gem instead!
42 | * remove "engine" cube, use the "ruby_engine" gem instead!
43 | * remove "info" cube, use the "ruby_info" gem instead!
44 | * remove "os" cube, use rdp's "os" gem instead!
45 | * remove "*_to_proc" cubes, use the "procstar" gem instead!
46 | * remove "sandbox" cube, since sandboxing is not recommended and removed from Ruby 2.1
47 | * remove "kernel" and "not" cube completely
48 | * tweaks to most other cubes
49 |
50 |
51 | 2013-04-30 | Zucker 13
52 | * fix alias_for bug
53 | * let RubyVersion#inspect and RubyEngine#inspect map to #to_s
54 | * remove Array#sum
55 | * repackage (gh#4)
56 |
57 |
58 | 2012-01-16 | Zucker 12
59 | * fix a requiring bug
60 | * rename zucker/version cube to zucker/ruby_version and Zucker::PACKAGES to Zucker::PACKS
61 | * remove more_aliases! (keep it simple...)
62 | * add case cube: String#to_camel and String#to_snake
63 |
64 |
65 | 2011-05-25 | Zucker 11
66 | * add Zucker::constants to check if cube has been required (e.g. Zucker::AliasFor if 'zucker/alias_for' is loaded)
67 | * rbx tweaks
68 | * don't define Binding#vars on rbx (prevent endless recursion)
69 | * sandbox-not-working warning
70 | * add Kernel#ignore_sigquit!
71 | * fix warnings
72 | * doc tweaks
73 |
74 |
75 | 2011-04-29 | Zucker 10
76 | * doc/spec tweaks
77 | * make test.rubygems.org-testable
78 | * fix zucker 9 permission issue
79 |
80 |
81 | 2011-01-22 | Zucker 9
82 | * remove history versions (sorry, it caused too much gem/rdoc troubles)
83 | * add file cube: File.delete! and File.gsub
84 | * debug pack improvements
85 | * binding: typos + return nil
86 | * cc: support for ripl + return nil
87 | * mm: also show eigenclass for modules + nicer displaying + return nil
88 | * added Regexp#visualize
89 | * remove optional sandbox param
90 | * rename xxx2proc to xxx_to_proc
91 | * change rakefile/rspec/gemspec structure
92 | * more minor fixes and improvements
93 |
94 |
95 | 2010-10-06 | Zucker 8
96 | * fix a little alias_for bug
97 | * disable rdoc creation when installing (in favour of the custom docs)
98 | * change Binding#inspect to Binding.variables (was too verbose and dangerous)
99 |
100 |
101 | 2010-10-03 | Zucker 7
102 | * fix critical OS.windows? bug
103 |
104 |
105 | 2010-10-03 | Zucker 6
106 | * no new cubes
107 | * bugfix for OS.posix?
108 | * small changes + bugfixes + doc improvements
109 | * add two user methods to Info
110 | * change egonil semantics ( using method_missing, see http://ruby.janlelis.de/26/catch_nil.rb )
111 | * bugfix for vv
112 |
113 |
114 | 2010-09-04 | Zucker 5
115 | * debug edition - add two debug helpers: oo (output line, method, file) and cc (output method callstack)
116 | * rename cube D to dd add add more debug aliases (for mm and binding)
117 | * fix __SPECIAL_VARS__ in info and kernel cube and some minor bugfixes
118 | * Zucker.activate_more_aliases! option
119 | * add Hash#&
120 | * add aliases: File.filename (for basename), Dir.join and Dir.split (for File.join, split)
121 | * add a flexible requiring mechansim in zucker.rb (no api changes)
122 | * restructure packages
123 | * add rake tasks for releasing
124 | * improve RubyVersion constant (cleaner and more flexible)
125 |
126 |
127 | 2010-09-01 | Zucker 4
128 | * fix Binding#inspect
129 | * add RubyEngine constant
130 | * add RubyVersion constant
131 | * add OS constant
132 | * add q debug method (like p but on one line)
133 | * add String#-
134 |
135 |
136 | 2010-08-14 | Zucker 3
137 | * add tap cube
138 | * add Object#not
139 | * add alias_for for an alternative alias syntax
140 | * add String#constantize (improved AS version)
141 | * improve Info module
142 | * make Array#sum Rails compatibile
143 | * improve docs
144 | * change directory layout (no changes for requiring)
145 | * more small changes
146 |
147 |
148 | 2010-08-08 | Zucker 2
149 | * add info cube
150 | * add chaining for array2proc
151 | * fix Hash.zip
152 | * fix instance_variables_from binding for 1.9
153 | * more specs
154 |
155 |
156 | 2010-08-06 | Zucker 1
157 | * initial release
158 |
159 |
160 | 2010-08-05 | Zucker 0
161 | * pre-release for rug-b talk
162 |
163 |
--------------------------------------------------------------------------------
/doc/create_documentation.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # creates the documentation for SugarRefinery
3 |
4 | require 'date'
5 | require 'yaml'
6 | require 'coderay'
7 |
8 | require_relative '../lib/sugar_refinery/camel_snake'
9 | using SugarRefinery::CamelSnake
10 |
11 |
12 | class SugarRefineryDoc
13 | ORDER = %w|summary use methods info spec source|
14 | DESCRIPTIONS = {
15 | 'summary' => 'Summary',
16 | 'use' => 'Activate',
17 | 'methods' => 'Usage',
18 | 'info' => 'Information',
19 | 'spec' => 'Specification',
20 | 'source' => 'Source',
21 | }
22 |
23 |
24 | class << self
25 | def generate(path = File.dirname(__FILE__) + '/../')
26 | @path = path
27 |
28 | # get version / date
29 | @version = SugarRefinery::VERSION
30 | @date = Date.today.to_s
31 |
32 | # include + format changelog
33 | @changelog = replace_html_special_chars File.read File.join( @path, 'CHANGELOG.md' )
34 |
35 | # collect description files and turn them into html
36 | @cubes = Dir[ File.join(path, 'doc', 'desc', '*.yaml') ].inject({}) do |res, cube_file; a|
37 | begin
38 | a = YAML.load_file cube_file
39 | rescue
40 | warn "Could not load the yaml file for #{ cube_file }"
41 | end
42 | if a.instance_of? Hash
43 | res.merge a
44 | else
45 | res
46 | end
47 | end.sort.map{ |name, hash| cube name, hash }.join
48 |
49 | output_path = File.join(path, 'doc', 'index.html')
50 | template = DATA.read
51 | template.gsub! /\.\.([a-z]+)\.\./i do eval "@#$1" end # substitute vars
52 | template.gsub! /⇧(.+?)⇧/, '\1'
53 | template.gsub! /●(.+?)●/, '\1'
54 | template.gsub! /→(.+?)→(.+?)→/, '\1'
55 | File.open(output_path, 'w'){ |file| file.puts(template) }
56 |
57 | puts "Created SugarRefinery documentation at #{File.expand_path(output_path)}"
58 | end
59 |
60 | private
61 |
62 | def cube(name, hash)
63 | @cube_name = name
64 | %{
| #{ DESCRIPTIONS[th] } | " + 72 | "#{ send th, td || name } |
|---|
The Ruby Sugar Refinery is a collection of tiny refinements (declarative local core extensions) for Ruby.
429 | 430 |432 | Add to Gemfile: 433 |
434 | 435 |gem 'sugar_refinery', require: 'sugar_refinery/all'
437 | 440 | Then add refinements to the current Ruby file or module: 441 |
using SugarRefinery::CamelSnake
443 | using SugarRefinery::HashZip
444 |
445 | "ClassName".to_snake # => "class_name"
446 | Hash.zip [1,2,3], [4,5,6] # => {1=>4, 2=>5, 3=>6}
447 | ..changelog..457 |
469 |
470 |
471 |
472 |
--------------------------------------------------------------------------------