├── .gitignore ├── .rspec ├── .ruby-gemset ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.textile ├── Rakefile ├── VERSION ├── boolean.gemspec ├── lib └── boolean.rb └── spec ├── boolean_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | # rcov generated 2 | coverage 3 | 4 | # rdoc generated 5 | rdoc 6 | 7 | # yard generated 8 | doc 9 | .yardoc 10 | 11 | # bundler 12 | .bundle 13 | 14 | # jeweler generated 15 | pkg 16 | 17 | # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: 18 | # 19 | # * Create a file at ~/.gitignore 20 | # * Include files you want ignored 21 | # * Run: git config --global core.excludesfile ~/.gitignore 22 | # 23 | # After doing this, these files will be ignored in all your git projects, 24 | # saving you from having to 'pollute' every project you touch with them 25 | # 26 | # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line) 27 | # 28 | # For MacOS: 29 | # 30 | #.DS_Store 31 | # 32 | # For TextMate 33 | #*.tmproj 34 | #tmtags 35 | # 36 | # For emacs: 37 | #*~ 38 | #\#* 39 | #.\#* 40 | # 41 | # For vim: 42 | #*.swp 43 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format=documentation 3 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | boolean 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.4.2 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :development do 4 | # FRAMEWORK 5 | gem 'jeweler' 6 | 7 | # SPECS 8 | gem 'rspec' 9 | 10 | # DOCS 11 | gem 'yard' 12 | gem 'RedCloth', require: nil 13 | end 14 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | RedCloth (4.3.2) 5 | addressable (2.4.0) 6 | builder (3.2.3) 7 | descendants_tracker (0.0.4) 8 | thread_safe (~> 0.3, >= 0.3.1) 9 | diff-lcs (1.3) 10 | faraday (0.9.2) 11 | multipart-post (>= 1.2, < 3) 12 | git (1.3.0) 13 | github_api (0.16.0) 14 | addressable (~> 2.4.0) 15 | descendants_tracker (~> 0.0.4) 16 | faraday (~> 0.8, < 0.10) 17 | hashie (>= 3.4) 18 | mime-types (>= 1.16, < 3.0) 19 | oauth2 (~> 1.0) 20 | hashie (3.5.6) 21 | highline (1.7.10) 22 | jeweler (2.3.7) 23 | builder 24 | bundler (>= 1) 25 | git (>= 1.2.5) 26 | github_api (~> 0.16.0) 27 | highline (>= 1.6.15) 28 | nokogiri (>= 1.5.10) 29 | psych (~> 2.2) 30 | rake 31 | rdoc 32 | semver2 33 | jwt (1.5.6) 34 | mime-types (2.99.3) 35 | mini_portile2 (2.3.0) 36 | multi_json (1.12.2) 37 | multi_xml (0.6.0) 38 | multipart-post (2.0.0) 39 | nokogiri (1.8.1) 40 | mini_portile2 (~> 2.3.0) 41 | oauth2 (1.4.0) 42 | faraday (>= 0.8, < 0.13) 43 | jwt (~> 1.0) 44 | multi_json (~> 1.3) 45 | multi_xml (~> 0.5) 46 | rack (>= 1.2, < 3) 47 | psych (2.2.4) 48 | rack (2.0.3) 49 | rake (12.3.0) 50 | rdoc (6.0.0) 51 | rspec (3.7.0) 52 | rspec-core (~> 3.7.0) 53 | rspec-expectations (~> 3.7.0) 54 | rspec-mocks (~> 3.7.0) 55 | rspec-core (3.7.0) 56 | rspec-support (~> 3.7.0) 57 | rspec-expectations (3.7.0) 58 | diff-lcs (>= 1.2.0, < 2.0) 59 | rspec-support (~> 3.7.0) 60 | rspec-mocks (3.7.0) 61 | diff-lcs (>= 1.2.0, < 2.0) 62 | rspec-support (~> 3.7.0) 63 | rspec-support (3.7.0) 64 | semver2 (3.4.2) 65 | thread_safe (0.3.6) 66 | yard (0.9.12) 67 | 68 | PLATFORMS 69 | ruby 70 | 71 | DEPENDENCIES 72 | RedCloth 73 | jeweler 74 | rspec 75 | yard 76 | 77 | BUNDLED WITH 78 | 1.16.0 79 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Tim Morgan 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 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. Boolean -- Additional Boolean-related core extensions 2 | 3 | | *Author* | Tim Morgan | 4 | | *Version* | 1.0 (Feb 15, 2011) | 5 | | *License* | Released under the MIT license. | 6 | 7 | h2. About 8 | 9 | *Boolean* adds some helpful methods for working with Ruby's Boolean types, 10 | @TrueClass@ and @FalseClass@ (the singleton classes whose only instances are 11 | @true@ and @false@, respectively). 12 | 13 | With *Boolean*, you get a @Boolean@ mixin so you can refer to @true@ and @false@ 14 | under a common class name: 15 | 16 |

17 |   if variable.kind_of?(Boolean) then
18 |     [ ... ]
19 |   end
20 | 
21 | 22 | You can also type-cast Ruby objects into their Boolean values: 23 | 24 |

25 |   "string".to_bool #=> true
26 |   nil.to_bool #=> false
27 | 
28 | 29 | And you can parse various Ruby objects to Booleans: 30 | 31 |

32 |   "yes".parse_bool #=> true
33 |   "no".parse_bool #=> false
34 |   1.parse_bool => true
35 |   0.parse_bool => false
36 | 
37 | 38 | (@parse_bool@ is also aliased as @to_b@ to be consistent with the 39 | @to_i@/@to_int@ naming paradigm.) 40 | 41 | Lastly, inline with the @Integer()@ method, you have a @Boolean()@ method: 42 | 43 |

44 |   Boolean("yes") #=> true
45 |   Boolean("no") #=> false
46 |   Boolean("maybe") #=> ArgumentError
47 | 
48 | 49 | h2. Installation and Usage 50 | 51 | Just add the gem to your project's @Gemfile@: 52 | 53 |

54 | gem 'boolean'
55 | 
56 | 57 | All the features shown in the previous section are now available in your project 58 | code. 59 | 60 | More information can be found in the class and method documentation. 61 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | #################################### BUNDLER ################################### 4 | 5 | require 'bundler' 6 | begin 7 | Bundler.setup(:default, :development) 8 | rescue Bundler::BundlerError => e 9 | $stderr.puts e.message 10 | $stderr.puts "Run `bundle install` to install missing gems" 11 | exit e.status_code 12 | end 13 | require 'rake' 14 | 15 | #################################### JEWELER ################################### 16 | 17 | require 'jeweler' 18 | Jeweler::Tasks.new do |gem| 19 | # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options 20 | gem.name = "boolean" 21 | gem.homepage = "http://rubygems.org/gems/boolean" 22 | gem.license = "MIT" 23 | gem.summary = %Q{Useful methods for working with Booleans} 24 | gem.description = %Q{This gem extends core classes, adding helpful methods for working with Booleans (such as #to_bool and #parse_bool, and a Boolean type).} 25 | gem.email = "git@timothymorgan.info" 26 | gem.authors = [ "Tim Morgan" ] 27 | end 28 | Jeweler::RubygemsDotOrgTasks.new 29 | 30 | ##################################### RSPEC #################################### 31 | 32 | require 'rspec/core' 33 | require 'rspec/core/rake_task' 34 | RSpec::Core::RakeTask.new(:spec) do |spec| 35 | spec.pattern = FileList['spec/**/*_spec.rb'] 36 | end 37 | 38 | task :default => :spec 39 | 40 | ##################################### YARD ##################################### 41 | 42 | require 'yard' 43 | YARD::Rake::YardocTask.new do |doc| 44 | doc.options << "-m" << "textile" 45 | doc.options << "--protected" 46 | doc.options << "--no-private" 47 | doc.options << "-r" << "README.textile" 48 | doc.options << "-o" << "doc" 49 | doc.options << "--title" << "Boolean Documentation".inspect 50 | 51 | doc.files = [ 'lib/**/*', 'README.textile' ] 52 | end 53 | 54 | desc "Generate API documentation" 55 | task :doc => :yard 56 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.1 -------------------------------------------------------------------------------- /boolean.gemspec: -------------------------------------------------------------------------------- 1 | # Generated by jeweler 2 | # DO NOT EDIT THIS FILE DIRECTLY 3 | # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' 4 | # -*- encoding: utf-8 -*- 5 | 6 | Gem::Specification.new do |s| 7 | s.name = %q{boolean} 8 | s.version = "1.0.1" 9 | 10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 11 | s.authors = ["Tim Morgan"] 12 | s.date = %q{2011-03-16} 13 | s.description = %q{This gem extends core classes, adding helpful methods for working with Booleans (such as #to_bool and #parse_bool, and a Boolean type).} 14 | s.email = %q{git@timothymorgan.info} 15 | s.extra_rdoc_files = [ 16 | "LICENSE.txt", 17 | "README.textile" 18 | ] 19 | s.files = [ 20 | ".rspec", 21 | "Gemfile", 22 | "Gemfile.lock", 23 | "LICENSE.txt", 24 | "README.textile", 25 | "Rakefile", 26 | "VERSION", 27 | "boolean.gemspec", 28 | "lib/boolean.rb", 29 | "spec/boolean_spec.rb", 30 | "spec/spec_helper.rb" 31 | ] 32 | s.homepage = %q{http://rubygems.org/gems/boolean} 33 | s.licenses = ["MIT"] 34 | s.require_paths = ["lib"] 35 | s.rubygems_version = %q{1.6.2} 36 | s.summary = %q{Useful methods for working with Booleans} 37 | s.test_files = [ 38 | "spec/boolean_spec.rb", 39 | "spec/spec_helper.rb" 40 | ] 41 | 42 | if s.respond_to? :specification_version then 43 | s.specification_version = 3 44 | 45 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then 46 | s.add_development_dependency(%q, [">= 0"]) 47 | s.add_development_dependency(%q, [">= 0"]) 48 | s.add_development_dependency(%q, [">= 0"]) 49 | s.add_development_dependency(%q, [">= 0"]) 50 | else 51 | s.add_dependency(%q, [">= 0"]) 52 | s.add_dependency(%q, [">= 0"]) 53 | s.add_dependency(%q, [">= 0"]) 54 | s.add_dependency(%q, [">= 0"]) 55 | end 56 | else 57 | s.add_dependency(%q, [">= 0"]) 58 | s.add_dependency(%q, [">= 0"]) 59 | s.add_dependency(%q, [">= 0"]) 60 | s.add_dependency(%q, [">= 0"]) 61 | end 62 | end 63 | 64 | -------------------------------------------------------------------------------- /lib/boolean.rb: -------------------------------------------------------------------------------- 1 | # Mixin module that adds no features, but simply includes a @Boolean@ type in 2 | # the parent class's heirarchy. This allows you to do things like: 3 | # 4 | #

  5 | #   if variable.kind_of?(Boolean) then
  6 | #     [ ... ]
  7 | #   end
  8 | # 
9 | 10 | module Boolean; end 11 | 12 | class TrueClass 13 | include Boolean 14 | 15 | # Returns the _typecasted_ value of this object. 16 | # 17 | # @return [true] @true@. 18 | def to_bool() true end 19 | 20 | # Returns the _parsed_ value of this object. 21 | # 22 | # @return [true] @true@. 23 | def parse_bool() true end 24 | 25 | # @see #parse_bool 26 | def to_b() true end 27 | end 28 | 29 | class FalseClass 30 | include Boolean 31 | 32 | # Returns the _typecasted_ value of this object. 33 | # 34 | # @return [false] @false@. 35 | def to_bool() false end 36 | 37 | # Returns the _parsed_ value of this object. 38 | # 39 | # @return [false] @false@. 40 | def parse_bool() false end 41 | 42 | # @see #parse_bool 43 | def to_b() false end 44 | end 45 | 46 | class NilClass 47 | # Returns the _typecasted_ value of this object. 48 | # 49 | # @return [false] @false@. 50 | def to_bool() false end 51 | 52 | # Returns the _parsed_ value of this object. 53 | # 54 | # @return [false] @false@. 55 | def parse_bool() false end 56 | 57 | # @see #parse_bool 58 | def to_b() false end 59 | end 60 | 61 | class Object 62 | # Returns the _typecasted_ value of this object. This would be @true@ for all 63 | # objects except @false@ and @nil@, which type-cast to @false@. 64 | # 65 | # @return [true, false] The typecast value of this object. 66 | def to_bool() true end 67 | end 68 | 69 | class String 70 | # Returns the _parsed_ value of this object. Strings beginning with any of 71 | # "y", "t", or "1" are considered @true@, whereas all else are considered 72 | # @false@. 73 | # 74 | # @return [true, false] The parsed Boolean value of this string. 75 | # @see #parse_bool! 76 | def parse_bool() %w( y Y 1 t T ).include? self[0,1] end 77 | 78 | # @see #parse_bool 79 | def to_b() parse_bool end 80 | 81 | # Similar to {#parse_bool}, but raises an error unless the string can be 82 | # explicitly parsed to @true@ or @false@. Strings beginning with "n", "f", or 83 | # "0" are considered false. 84 | # 85 | # @return [true, false] The parsed Boolean value of this string. 86 | # @raise [ArgumentError] If the string does not seem to represent @true@ or 87 | # @false@. 88 | # @example 89 | # "true".parse_bool! #=> true 90 | # "no".parse_bool! #=> false 91 | # "maybe".parse_bool! #=> ArgumentError 92 | def parse_bool! 93 | if %w( y Y 1 t T ).include? self[0,1] then 94 | true 95 | elsif %w( n N 0 f F ).include? self[0,1] then 96 | false 97 | else 98 | raise ArgumentError, "Invalid value for parse_bool!: #{inspect}" 99 | end 100 | end 101 | 102 | # @see #parse_bool! 103 | def to_b!() parse_bool! end 104 | end 105 | 106 | module Kernel 107 | # @see String#parse_bool! 108 | def Boolean(string) 109 | string.parse_bool! 110 | rescue ArgumentError => err 111 | raise ArgumentError, err.message.gsub('parse_bool!', 'Boolean()') 112 | end 113 | end 114 | 115 | class Numeric 116 | # Returns the _parsed_ value of this object. Numbers equal to zero are 117 | # considered @false@; all others are considered @true@. 118 | # 119 | # @return [true, false] The parsed Boolean value of this number. 120 | def parse_bool() not zero? end 121 | 122 | # @see #parse_bool 123 | def to_b() not zero? end 124 | end 125 | -------------------------------------------------------------------------------- /spec/boolean_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe TrueClass do 4 | [ :to_bool, :parse_bool, :to_b ].each do |method| 5 | describe "##{method}" do 6 | it("should return true") { expect(true.send(method)).to eql(true) } 7 | end 8 | end 9 | 10 | it("should be a kind of Boolean") { expect(true).to be_kind_of(Boolean) } 11 | end 12 | 13 | describe FalseClass do 14 | [ :to_bool, :parse_bool, :to_b ].each do |method| 15 | describe "##{method}" do 16 | it("should return false") { expect(false.send(method)).to eql(false) } 17 | end 18 | end 19 | 20 | it("should be a kind of Boolean") { expect(false).to be_kind_of(Boolean) } 21 | end 22 | 23 | describe NilClass do 24 | [ :to_bool, :parse_bool, :to_b ].each do |method| 25 | describe "##{method}" do 26 | it("should return false") { expect(nil.send(method)).to eql(false) } 27 | end 28 | end 29 | end 30 | 31 | describe Object do 32 | describe "#to_bool" do 33 | it("should return true") { expect(Object.new.to_bool).to eql(true) } 34 | end 35 | 36 | it("should not be a kind of Boolean") { expect(Object.new).not_to be_kind_of(Boolean) } 37 | end 38 | 39 | describe Numeric do 40 | [ :parse_bool, :to_b ].each do |method| 41 | describe "##{method}" do 42 | it "should return true if the number is not zero" do 43 | expect(1.send(method)).to eql(true) 44 | expect(1.0.send(method)).to eql(true) 45 | expect(-1.send(method)).to eql(true) 46 | expect(-1.0.send(method)).to eql(true) 47 | end 48 | 49 | it "should return false if the number is zero" do 50 | expect(0.send(method)).to eql(false) 51 | expect(0.0.send(method)).to eql(false) 52 | end 53 | end 54 | end 55 | end 56 | 57 | describe String do 58 | [ :parse_bool, :to_b ].each do |method| 59 | describe "##{method}" do 60 | it "should return true if the string starts with 1, y, Y, t, or T" do 61 | expect("y".send(method)).to eql(true) 62 | expect("Y".send(method)).to eql(true) 63 | expect("yes".send(method)).to eql(true) 64 | expect("YES".send(method)).to eql(true) 65 | expect("Yes".send(method)).to eql(true) 66 | expect("t".send(method)).to eql(true) 67 | expect("T".send(method)).to eql(true) 68 | expect("true".send(method)).to eql(true) 69 | expect("TRUE".send(method)).to eql(true) 70 | expect("True".send(method)).to eql(true) 71 | expect("1".send(method)).to eql(true) 72 | end 73 | 74 | it "should return false otherwise" do 75 | expect("n".send(method)).to eql(false) 76 | expect("N".send(method)).to eql(false) 77 | expect("no".send(method)).to eql(false) 78 | expect("NO".send(method)).to eql(false) 79 | expect("No".send(method)).to eql(false) 80 | expect("f".send(method)).to eql(false) 81 | expect("F".send(method)).to eql(false) 82 | expect("false".send(method)).to eql(false) 83 | expect("FALSE".send(method)).to eql(false) 84 | expect("False".send(method)).to eql(false) 85 | expect("0".send(method)).to eql(false) 86 | expect("".send(method)).to eql(false) 87 | 88 | expect("m".send(method)).to eql(false) 89 | expect("maybe".send(method)).to eql(false) 90 | expect("MAYBE".send(method)).to eql(false) 91 | expect("Maybe".send(method)).to eql(false) 92 | expect("i".send(method)).to eql(false) 93 | expect("I".send(method)).to eql(false) 94 | expect("i don't know".send(method)).to eql(false) 95 | expect("I DON'T KNOW".send(method)).to eql(false) 96 | expect("I don't know".send(method)).to eql(false) 97 | end 98 | end 99 | end 100 | 101 | [ :parse_bool!, :to_b! ].each do |method| 102 | describe "##{method}" do 103 | it "should return true if the string starts with 1, y, Y, t, or T" do 104 | expect("y".send(method)).to eql(true) 105 | expect("Y".send(method)).to eql(true) 106 | expect("yes".send(method)).to eql(true) 107 | expect("YES".send(method)).to eql(true) 108 | expect("Yes".send(method)).to eql(true) 109 | expect("t".send(method)).to eql(true) 110 | expect("T".send(method)).to eql(true) 111 | expect("true".send(method)).to eql(true) 112 | expect("TRUE".send(method)).to eql(true) 113 | expect("True".send(method)).to eql(true) 114 | expect("1".send(method)).to eql(true) 115 | end 116 | 117 | it "should return false if the string starts with 0, n, N, f, or F" do 118 | expect("n".send(method)).to eql(false) 119 | expect("N".send(method)).to eql(false) 120 | expect("no".send(method)).to eql(false) 121 | expect("NO".send(method)).to eql(false) 122 | expect("No".send(method)).to eql(false) 123 | expect("f".send(method)).to eql(false) 124 | expect("F".send(method)).to eql(false) 125 | expect("false".send(method)).to eql(false) 126 | expect("FALSE".send(method)).to eql(false) 127 | expect("False".send(method)).to eql(false) 128 | expect("0".send(method)).to eql(false) 129 | end 130 | 131 | it "should raise ArgumentError otherwise" do 132 | expect { "m".send(method) }.to raise_error(ArgumentError) 133 | expect { "maybe".send(method) }.to raise_error(ArgumentError) 134 | expect { "MAYBE".send(method) }.to raise_error(ArgumentError) 135 | expect { "Maybe".send(method) }.to raise_error(ArgumentError) 136 | expect { "i".send(method) }.to raise_error(ArgumentError) 137 | expect { "I".send(method) }.to raise_error(ArgumentError) 138 | expect { "i don't know".send(method) }.to raise_error(ArgumentError) 139 | expect { "I DON'T KNOW".send(method) }.to raise_error(ArgumentError) 140 | expect { "I don't know".send(method) }.to raise_error(ArgumentError) 141 | expect { "".send(method) }.to raise_error(ArgumentError) 142 | end 143 | end 144 | end 145 | end 146 | 147 | describe Kernel do 148 | describe "#Boolean" do 149 | it "should call String#parse_bool! and return the result" do 150 | string = double('String') 151 | result = double('result') 152 | 153 | expect(string).to receive(:parse_bool!).once.and_return(result) 154 | 155 | expect(Boolean(string)).to eql(result) 156 | end 157 | end 158 | end 159 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 2 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 3 | require 'rspec' 4 | require 'boolean' 5 | 6 | # Requires supporting files with custom matchers and macros, etc, 7 | # in ./support/ and its subdirectories. 8 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } 9 | 10 | RSpec.configure do |config| 11 | # configuration here 12 | end 13 | --------------------------------------------------------------------------------