finishing_moves 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Vagrantfile ADDED
@@ -0,0 +1,44 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ NAME = "finishing-moves"
5
+ FQDN = "#{NAME}.example.com"
6
+
7
+ Vagrant.configure("2") do |config|
8
+ # "trusty" is 14.04
9
+ config.vm.box = "trusty32"
10
+ config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-i386-vagrant-disk1.box"
11
+
12
+ config.vm.provider :virtualbox do |vb|
13
+ vb.customize ["modifyvm", :id,
14
+ # Basics.
15
+ "--name", NAME,
16
+ "--memory", 4096,
17
+ # I/O APIC must be enabled to support a multi-core guest.
18
+ "--cpus", 4,
19
+ "--ioapic", "on",
20
+ # Enable native host virtualization features (yields better performance).
21
+ "--pae", "on",
22
+ "--hwvirtex", "on",
23
+ "--largepages", "on",
24
+ "--vtxvpid", "on",
25
+ # This causes the virtual machine to proxy DNS requests through the host
26
+ # via NAT. Without this, the default resolver on the guest will introduce
27
+ # a 5 second latency on every HTTP request... which is a real downer.
28
+ "--natdnshostresolver1", "on"
29
+ ]
30
+ end
31
+
32
+ config.vm.hostname = FQDN
33
+ config.vm.provision :shell, path: "provision.sh"
34
+ end
35
+
36
+ #
37
+ # DONT FORGET!
38
+ #
39
+ # Force update VirtualBox Guest Additions
40
+ # Run the following command inside same directory as Vagrantfile
41
+ # Must be done once on your dev system
42
+ #
43
+ # vagrant plugin install vagrant-vbguest
44
+ #
@@ -0,0 +1,31 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "finishing_moves/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ s.name = "finishing_moves"
8
+ s.version = FinishingMoves::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Frank Koehl", "Chris Tonkinson"]
11
+ s.email = ["frank@forgecrafted.com", "chris@forgecrafted.com"]
12
+ s.summary = %q{Small, focused, incredibly useful methods added to core Ruby classes.}
13
+ s.description = <<-EOF
14
+ Ruby includes a huge amount of default awesomeness that tackles most common development challenges. But every now and then, you find yourself in a situation where an elaborate-yet-precise coding maneuver wins the day. Finishing Moves is a collection of methods designed to assist in those just-typical-enough-to-be-annoying scenarios.
15
+
16
+ In gamer terms, if standard Ruby methods are your default actions, finishing_moves would be mana-consuming techniques. Your cooldown spells. Your grenades (there's never enough grenades). In the right situation, they kick serious cyclomatic butt.
17
+ EOF
18
+ s.homepage = "https://github.com/forgecrafted/finishing_moves"
19
+ s.license = "MIT"
20
+
21
+ s.files = `git ls-files -z`.split("\x0")
22
+ s.test_files = Dir["spec/**/*"]
23
+
24
+ s.add_development_dependency 'rb-readline', '>= 0'
25
+ s.add_development_dependency 'rspec', '~> 3.1.0'
26
+ s.add_development_dependency 'priscilla', '>= 0'
27
+ s.add_development_dependency 'pry-byebug', '>= 0'
28
+ s.add_development_dependency 'fuubar', '>= 0'
29
+
30
+ s.required_ruby_version = '>= 2.0'
31
+ end
@@ -0,0 +1,7 @@
1
+ module FinishingMoves
2
+
3
+ Dir[File.dirname(__FILE__) + '/finishing_moves/*.rb'].each do |file|
4
+ require file
5
+ end
6
+
7
+ end
@@ -0,0 +1,23 @@
1
+ class Fixnum
2
+ def length
3
+ Math.log10(self.abs).to_i + 1
4
+ end
5
+ end
6
+
7
+ class Bignum
8
+ def length
9
+ Math.log10(self.abs).to_i + 1
10
+ end
11
+ end
12
+
13
+ class Float
14
+ def length
15
+ raise ArgumentError.new("Cannot get length: \"#{self}\" is not an integer")
16
+ end
17
+ end
18
+
19
+ class BigDecimal
20
+ def length
21
+ raise ArgumentError.new("Cannot get length: \"#{self}\" is not an integer")
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ class Hash
2
+
3
+ # When deleting a value from a hash, return the remaining hash, instead of the deleted value
4
+ def delete!(key)
5
+ self.delete(key)
6
+ return self
7
+ end
8
+
9
+ # Delete all records according to the keys passed in as an array, and return a hash of deleted
10
+ # entries. Silently ignores any keys which are not found.
11
+ def delete_each(*hash_keys)
12
+ deleted_entries = {}
13
+ hash_keys.each do |hash_key|
14
+ value = self.delete(hash_key)
15
+ deleted_entries[hash_key] = value unless value.nil?
16
+ end
17
+ return deleted_entries unless deleted_entries.empty?
18
+ nil
19
+ end
20
+
21
+ # Delete all records according to the keys passed in as array, and return the remaining hash.
22
+ def delete_each!(*keys)
23
+ self.delete_each(*keys)
24
+ return self
25
+ end
26
+
27
+ end
@@ -0,0 +1,42 @@
1
+ class Object
2
+
3
+ def nil_chain(ret_val = nil, &block)
4
+ begin
5
+ result = yield
6
+ return ret_val if result.nil?
7
+ result
8
+ rescue NoMethodError
9
+ rescue NameError
10
+ return ret_val
11
+ end
12
+ end
13
+ alias_method :chain, :nil_chain
14
+ alias_method :method_chain, :nil_chain
15
+
16
+ def bool_chain(&block)
17
+ result = nil_chain(&block)
18
+ return false if result.nil?
19
+ result
20
+ end
21
+
22
+ def class_exists?(class_name)
23
+ klass = Module.const_get(class_name.to_s)
24
+ return klass.is_a?(Class)
25
+ rescue NameError
26
+ return false
27
+ end
28
+
29
+ def not_nil?
30
+ !self.nil?
31
+ end
32
+
33
+ def same_as(compare)
34
+ if compare.respond_to? :to_s
35
+ self.to_s == compare.to_s
36
+ else
37
+ raise ArgumentError.new("Cannot compare \"#{self.class.name}\" to \"#{compare.class.name}\", no string conversion")
38
+ end
39
+ end
40
+
41
+
42
+ end
@@ -0,0 +1,33 @@
1
+ class String
2
+ def to_bool
3
+ return true if self == true || self =~ (/^(1|t(rue)?|y(es)?|on)$/i)
4
+ return false if self == false || self == "" || self =~ /\A[[:space:]]*\z/ || self =~ (/^(0|f(alse)?|no?|off)$/i)
5
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
6
+ end
7
+ end
8
+
9
+ class Fixnum
10
+ def to_bool
11
+ return true if self == 1
12
+ return false if self == 0
13
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
14
+ end
15
+ end
16
+
17
+ class TrueClass
18
+ def to_bool; self; end
19
+ def to_i; 1; end
20
+ def to_sym; :true; end
21
+ end
22
+
23
+ class FalseClass
24
+ def to_bool; self; end
25
+ def to_i; 0; end
26
+ def to_sym; :false; end
27
+ end
28
+
29
+ class NilClass
30
+ def to_bool; false; end
31
+ def to_i; 0; end
32
+ def to_sym; :nil; end
33
+ end
@@ -0,0 +1,3 @@
1
+ module FinishingMoves
2
+ VERSION = "0.1.1"
3
+ end
data/provision.sh ADDED
@@ -0,0 +1,71 @@
1
+ #!/bin/bash
2
+
3
+ # Shell user settings.
4
+ USER_NAME=vagrant
5
+ USER_HOME=/home/$USER_NAME
6
+ DEFAULT_RUBY='2.1.5'
7
+
8
+ ###############################################################################
9
+ # Functions
10
+ ###############################################################################
11
+ # Most of the time we can get by with this DRY wrapper for sudo commands.
12
+ as_user() {
13
+ echo "$USER_NAME:~$ > ${*}"
14
+ su -l $USER_NAME -c "$*"
15
+ }
16
+
17
+ # Install the requested version of Ruby, with Bundler.
18
+ install_ruby() {
19
+ as_user "rbenv install -s $1"
20
+ as_user "RBENV_VERSION=$1 gem install bundler"
21
+ as_user "rbenv rehash"
22
+ }
23
+
24
+ ###############################################################################
25
+ # Base System
26
+ ###############################################################################
27
+ apt-get -y update
28
+ apt-get -yfV dist-upgrade
29
+
30
+ ###############################################################################
31
+ # rbenv & ruby-build, and Rubies
32
+ # From https://github.com/sstephenson/rbenv
33
+ # and https://github.com/sstephenson/ruby-build
34
+ ###############################################################################
35
+
36
+ # Install dependencies.
37
+ apt-get install -yfV \
38
+ build-essential \
39
+ curl \
40
+ git-core \
41
+ libcurl4-openssl-dev \
42
+ libreadline-dev \
43
+ libsqlite3-dev \
44
+ libssl-dev \
45
+ libxml2-dev \
46
+ libxslt1-dev \
47
+ libyaml-dev \
48
+ python-software-properties \
49
+ sqlite3 \
50
+ wget \
51
+ zlib1g-dev \
52
+
53
+ # Install rbenv and ruby-build.
54
+ as_user "git clone https://github.com/sstephenson/rbenv.git $USER_HOME/.rbenv"
55
+ as_user "git clone https://github.com/sstephenson/ruby-build.git $USER_HOME/.rbenv/plugins/ruby-build"
56
+
57
+ # Setup bash to use rbenv for $USER_NAME.
58
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> $USER_HOME/.bashrc
59
+ echo 'eval "$(rbenv init -)"' >> $USER_HOME/.bashrc
60
+ echo 'cd /vagrant' >> $USER_HOME/.bashrc
61
+ echo 'gem: --no-document' >> $USER_HOME/.gemrc
62
+
63
+ # Install Ruby for $USER_NAME.
64
+ install_ruby $DEFAULT_RUBY
65
+ echo $DEFAULT_RUBY > $USER_HOME/.ruby-version
66
+
67
+ ###############################################################################
68
+ # EDIT HERE!
69
+ # Install any Rubies (other than $DEFAULT_RUBY) required for individual apps.
70
+ ###############################################################################
71
+ # e.g. `install_ruby 2.1.4`
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Count number length" do
4
+
5
+ it "Fixnum#length" do
6
+ expect(1.length).to eq 1
7
+ expect(5.length).to eq 1
8
+ expect(9.length).to eq 1
9
+ expect(90.length).to eq 2
10
+ expect(900.length).to eq 3
11
+ expect(9000.length).to eq 4
12
+ expect(-9000.length).to eq 4
13
+ end
14
+
15
+ it "Bignum#length" do
16
+ expect(12356469787881584554556.length).to eq 23
17
+ expect(-12356469787881584554556.length).to eq 23
18
+ end
19
+
20
+ it "Float#length" do
21
+ expect{ 0.0.length }.to raise_error(ArgumentError)
22
+ expect{ 1.0.length }.to raise_error(ArgumentError)
23
+ expect{ -1.0.length }.to raise_error(ArgumentError)
24
+ expect{ 3.14.length }.to raise_error(ArgumentError)
25
+ expect{ 12356469.987.length }.to raise_error(ArgumentError)
26
+ end
27
+
28
+ it "BigDecimal#length" do
29
+ expect{ 1265437718438866624512.123.length }.to raise_error(ArgumentError)
30
+ expect{ -1265437718438866624512.123.length }.to raise_error(ArgumentError)
31
+ expect{ 0.9999999999999062.length }.to raise_error(ArgumentError)
32
+ expect{ -0.9999999999999062.length }.to raise_error(ArgumentError)
33
+ end
34
+
35
+ end
data/spec/hash_spec.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+
5
+ let :test_hash do
6
+ { :foo => :bar, :baz => :bin, :flo => :bie }
7
+ end
8
+
9
+ it "#delete!" do
10
+ expect(test_hash.delete!(:bogus)).to eq({ :foo => :bar, :baz => :bin, :flo => :bie })
11
+ expect(test_hash.delete!(:baz)).to eq({ :foo => :bar, :flo => :bie })
12
+ end
13
+
14
+ it "#delete_each" do
15
+ expect(test_hash.delete_each(:bogus, :bar)).to eq nil
16
+ expect(test_hash).to eq({ :foo => :bar, :baz => :bin, :flo => :bie })
17
+ expect(test_hash.delete_each(:flo)).to eq({ :flo => :bie })
18
+ expect(test_hash).to eq({ :foo => :bar, :baz => :bin })
19
+ expect(test_hash.delete_each(:foo, :baz, :bogus)).to eq({ :foo => :bar, :baz => :bin })
20
+ expect(test_hash).to eq({ })
21
+ end
22
+
23
+ it "#delete_each!" do
24
+ expect(test_hash.delete_each!(:bogus, :bar)).to eq({ :foo => :bar, :baz => :bin, :flo => :bie })
25
+ expect(test_hash.delete_each!(:flo)).to eq({ :foo => :bar, :baz => :bin })
26
+ expect(test_hash.delete_each!(:bogus, :flo, :foo)).to eq({ :baz => :bin })
27
+ expect(test_hash.delete_each!(:baz)).to eq({ })
28
+ end
29
+
30
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Object do
4
+
5
+ it "#nil_chain" do
6
+ expect(nil_chain{bogus_variable}).to eq nil
7
+ expect(nil_chain{bogus_hash[:foo]}).to eq nil
8
+ params = { :foo => 'bar' }
9
+ expect(nil_chain{ params[:bogus_key] }).to eq nil
10
+ expect(nil_chain{ params[:foo] }).to eq 'bar'
11
+ var = 'a simple string'
12
+ expect(nil_chain{ var.transmogrify }).to eq nil
13
+
14
+ c = C.new
15
+ b = B.new c
16
+ a = A.new b
17
+ expect(a.b.c.hello).to eq "Hello, world!"
18
+ b.c = nil
19
+ expect(method_chain{a.b.c.hello}).to eq nil
20
+ a = nil
21
+ expect(method_chain{a.b.c.hello}).to eq nil
22
+
23
+ expect( chain(true) { bogus_variable } ).to equal true
24
+ expect( chain(false) { bogus_variable } ).to equal false
25
+ expect( chain('gotcha!') { bogus_variable } ).to eq 'gotcha!'
26
+ expect( chain('gotcha!') { params[:bogus_key] } ).to eq 'gotcha!'
27
+ expect( chain('gotcha!') { params[:foo] } ).to eq 'bar'
28
+ end
29
+
30
+ it "#bool_chain" do
31
+ expect(bool_chain{bogus_variable}).to equal false
32
+ var = true
33
+ expect(bool_chain{var}).to equal true
34
+ var = 'foo'
35
+ expect(bool_chain{var}).to eq 'foo'
36
+ result = bool_chain{ var.transmogrify }
37
+ expect(result).to equal false
38
+ end
39
+
40
+ it "#class_exists?" do
41
+ expect(class_exists? :Symbol).to eq true
42
+ expect(class_exists? :Symbology).to eq false
43
+ expect(class_exists? 'Symbol').to eq true
44
+ expect(class_exists? 'Symbology').to eq false
45
+ expect(class_exists? :Array).to eq true
46
+ expect(class_exists? :aRRay).to eq false
47
+ expect(class_exists? :ARRAY).to eq false
48
+ end
49
+
50
+ it "#not_nil?" do
51
+ var = nil
52
+ expect(var.not_nil?).to eq false
53
+ var = 'foobar'
54
+ expect(var.not_nil?).to eq true
55
+ end
56
+
57
+ it "#same_as" do
58
+ expect(:symbol.same_as 'symbol').to eq true
59
+ expect('symbol'.same_as :symbol).to eq true
60
+ expect('1'.same_as 1).to eq true
61
+ expect(2.same_as '2').to eq true
62
+ expect(3.same_as 3).to eq true
63
+ expect(:symbol.same_as :SYMBOL).to eq false
64
+
65
+ user = User.new
66
+ expect(:faceless_one.same_as(user)).to eq true
67
+ expect(user.same_as(:faceless_one)).to eq true
68
+ expect(user.same_as(:FACELESS_ONE)).to eq false
69
+ end
70
+
71
+ end
72
+
73
+ # test classes
74
+
75
+ class A
76
+ attr_accessor :b
77
+ def initialize(b)
78
+ @b = b
79
+ end
80
+ end
81
+
82
+ class B
83
+ attr_accessor :c
84
+ def initialize(c)
85
+ @c = c
86
+ end
87
+ end
88
+
89
+ class C
90
+ def hello
91
+ "Hello, world!"
92
+ end
93
+ end
94
+
95
+ class User
96
+ attr_writer :handle
97
+
98
+ def handle
99
+ @handle || "faceless_one"
100
+ end
101
+
102
+ def to_s
103
+ handle.to_s
104
+ end
105
+ end