buff-extensions-2.0.0/0000755000004100000410000000000012754217533014671 5ustar www-datawww-databuff-extensions-2.0.0/Thorfile0000644000004100000410000000204212754217533016366 0ustar www-datawww-data# encoding: utf-8 $:.push File.expand_path("../lib", __FILE__) require 'bundler' require 'bundler/setup' require 'buff/ruby_engine' require 'buff/extensions/version' class Default < Thor extend Buff::RubyEngine unless jruby? require 'thor/rake_compat' include Thor::RakeCompat Bundler::GemHelper.install_tasks desc "build", "Build buff-extensions-#{Buff::Extensions::VERSION}.gem into the pkg directory" def build Rake::Task["build"].invoke end desc "install", "Build and install buff-extensions-#{Buff::Extensions::VERSION}.gem into system gems" def install Rake::Task["install"].invoke end desc "release", "Create tag v#{Buff::Extensions::VERSION} and build and push buff-extensions-#{Buff::Extensions::VERSION}.gem to Rubygems" def release Rake::Task["release"].invoke end end class Spec < Thor namespace :spec default_task :unit desc "unit", "run the project's unit tests" def unit exec "rspec --color --format=documentation spec" end end end buff-extensions-2.0.0/Gemfile0000644000004100000410000000004712754217533016165 0ustar www-datawww-datasource 'https://rubygems.org' gemspec buff-extensions-2.0.0/buff-extensions.gemspec0000644000004100000410000000242112754217533021354 0ustar www-datawww-data# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'buff/extensions/version' Gem::Specification.new do |spec| spec.name = "buff-extensions" spec.version = Buff::Extensions::VERSION spec.authors = ["Jamie Winsor"] spec.email = ["jamie@vialstudios.com"] spec.description = %q{Extensions to Core Ruby classes} spec.summary = spec.description spec.homepage = "https://github.com/RiotGames/buff-extensions" spec.license = "Apache 2.0" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^spec/}) spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.2.0" spec.add_development_dependency "buff-ruby_engine", "~> 0.1" spec.add_development_dependency "thor", "~> 0.18.0" spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" spec.add_development_dependency "fuubar" spec.add_development_dependency "guard" spec.add_development_dependency "guard-rspec" spec.add_development_dependency "guard-spork" spec.add_development_dependency "spork" end buff-extensions-2.0.0/.ruby-version0000644000004100000410000000000612754217533017332 0ustar www-datawww-data2.3.1 buff-extensions-2.0.0/spec/0000755000004100000410000000000012754217533015623 5ustar www-datawww-databuff-extensions-2.0.0/spec/buff/0000755000004100000410000000000012754217533016545 5ustar www-datawww-databuff-extensions-2.0.0/spec/buff/extensions/0000755000004100000410000000000012754217533020744 5ustar www-datawww-databuff-extensions-2.0.0/spec/buff/extensions/hash/0000755000004100000410000000000012754217533021667 5ustar www-datawww-databuff-extensions-2.0.0/spec/buff/extensions/hash/dotted_paths_spec.rb0000644000004100000410000000727512754217533025723 0ustar www-datawww-datarequire 'spec_helper' describe Buff::Extensions::Hash::DottedPaths do describe "ClassMethods" do subject { Hash } describe "::from_dotted_path" do it "returns a new Hash" do expect(subject.from_dotted_path("deep.nested.item")).to be_a(Hash) end it "returns a hash containing the nested keys" do obj = subject.from_dotted_path("deep.nested.item") expect(obj).to have_key("deep") expect(obj["deep"]).to have_key("nested") expect(obj["deep"]["nested"]).to have_key("item") end it "sets a nil value for the deepest nested item" do obj = subject.from_dotted_path("deep.nested.item") expect(obj["deep"]["nested"]["item"]).to be_nil end it "handles a symbol as the dotted path" do obj = subject.from_dotted_path(:"a.b.c", "value") expect(obj["a"]["b"]["c"]).to eql("value") end context "when given a seed value" do it "sets the value of the deepest nested item to the seed" do obj = subject.from_dotted_path("deep.nested.item", "seeded_value") expect(obj["deep"]["nested"]["item"]).to eql("seeded_value") end end end end subject { Hash.new } describe "#berks_dig" do context "when the Hash contains the nested path" do subject do { "we" => { "found" => { "something" => true } } } end it "returns the value at the dotted path" do expect(subject.berks_dig("we.found.something")).to eql(true) end end context "when the Hash does not contain the nested path" do it "returns a nil value" do expect(subject.berks_dig("nothing.is.here")).to be_nil end end context "when the Hash contains symbols for keys" do subject do { we: { found: { something: :symbol_value } } } end it "returns the value at the dotted path" do expect(subject.berks_dig("we.found.something")).to eql(:symbol_value) end end it "returns nil if given a blank string" do expect(subject.berks_dig("")).to be_nil end it "returns 'false' nested values as 'false' and not 'nil'" do hash = { "ssl" => { "verify" => false } } expect(hash.berks_dig('ssl.verify')).to eql(false) end end describe "#dotted_paths" do it "returns an array" do expect(subject.dotted_paths).to be_a(Array) end context "given a hash with only top level keys" do subject do { "one" => "val", "two" => "val" } end it "returns an array of the top level keys as strings" do expect(subject.dotted_paths).to eql(["one", "two"]) end end context "given a hash with empty hashes as values" do subject do { "one" => Hash.new, "two" => Hash.new } end it "returns an array of the top level keys as strings" do expect(subject.dotted_paths).to eql(["one", "two"]) end end context "given a hash with nested keys" do subject do { "one" => { "nested" => { "attribute" => "hello" } }, "two" => { "nested" => { "attribute" => "other_hello", "other_attr" => "world" } } } end it "returns an array of dotted paths including the nested Hash keys" do expect(subject.dotted_paths).to eql(["one.nested.attribute", "two.nested.attribute", "two.nested.other_attr"]) end end end end buff-extensions-2.0.0/spec/spec_helper.rb0000644000004100000410000000101112754217533020432 0ustar www-datawww-data$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'rspec' require 'buff/ruby_engine' def setup_rspec RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect end config.mock_with :rspec config.filter_run focus: true config.run_all_when_everything_filtered = true end end if Buff::RubyEngine.jruby? require 'buff/extensions' setup_rspec else require 'spork' Spork.prefork { setup_rspec } Spork.each_run { require 'buff/extensions' } end buff-extensions-2.0.0/.travis.yml0000644000004100000410000000036212754217533017003 0ustar www-datawww-datalanguage: ruby cache: - bundler dist: trusty branches: only: - master before_install: - gem update --system - gem install bundler script: "bundle exec thor spec" matrix: include: - rvm: 2.2.5 - rvm: 2.3.1 - rvm: ruby-head buff-extensions-2.0.0/lib/0000755000004100000410000000000012754217533015437 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/0000755000004100000410000000000012754217533016361 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions.rb0000644000004100000410000000041512754217533021105 0ustar www-datawww-datamodule Buff module Extensions require_relative 'extensions/version' end end require_relative 'extensions/boolean' require_relative 'extensions/hash' require_relative 'extensions/kernel' require_relative 'extensions/object' require_relative 'extensions/string' buff-extensions-2.0.0/lib/buff/extensions/0000755000004100000410000000000012754217533020560 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions/string.rb0000644000004100000410000000004612754217533022413 0ustar www-datawww-datarequire_relative 'string/inflections' buff-extensions-2.0.0/lib/buff/extensions/hash.rb0000644000004100000410000000025712754217533022034 0ustar www-datawww-datarequire_relative 'hash/dotted_paths' require_relative 'hash/except' require_relative 'hash/key_transforms' require_relative 'hash/reverse_merge' require_relative 'hash/slice' buff-extensions-2.0.0/lib/buff/extensions/object.rb0000644000004100000410000000007612754217533022356 0ustar www-datawww-datarequire_relative 'object/blank' require_relative 'object/try' buff-extensions-2.0.0/lib/buff/extensions/hash/0000755000004100000410000000000012754217533021503 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions/hash/reverse_merge.rb0000644000004100000410000000064112754217533024663 0ustar www-datawww-datamodule Buff module Extensions::Hash module ReverseMerge # @param [Hash] other # # @return [Hash] def reverse_merge(other) other.merge(self) end # @param [Hash] other # # @return [Hash] def reverse_merge!(other) merge!(other) { |key, old, new| old } end end end end class Hash include Buff::Extensions::Hash::ReverseMerge end buff-extensions-2.0.0/lib/buff/extensions/hash/dotted_paths.rb0000644000004100000410000000671112754217533024517 0ustar www-datawww-datamodule Buff module Extensions::Hash module DottedPaths class << self def included(base) base.send(:extend, ClassMethods) end end module ClassMethods # Create a new Hash containing other nested Hashes from a string containing # a dotted path. A Hash will be created and assigned to a key of another Hash # for each entry in the dotted path. # # If a value is provided for the optional seed argument then the value of the # deepest nested key will be set to the given value. If no value is provided # the value of the key will be nil. # # @example creating a nested hash from a dotted path # # Hash.from_dotted_path("deep.nested.hash") => # { # "deep" => { # "nested" => { # "hash" => nil # } # } # } # # # @example specifying a seed value # # Hash.from_dotted_path("deep.nested.hash", :seed_value) => # { # "deep" => { # "nested" => { # "hash" => :seed_value # } # } # } # # @param [String, Symbol, Array] dotpath # @param [Object] seed (nil) # @param [Hash] target (self.new) # # @return [Hash] def from_dotted_path(dotpath, seed = nil, target = self.new) case dotpath when String, Symbol from_dotted_path(dotpath.to_s.split("."), seed) when Array if dotpath.empty? return target end key = dotpath.pop if target.empty? target[key] = seed from_dotted_path(dotpath, seed, target) else new_target = self.new new_target[key] = target from_dotted_path(dotpath, seed, new_target) end end end end # Return the value of the nested hash key from the given dotted path # # @example # # nested_hash = { # "deep" => { # "nested" => { # "hash" => :seed_value # } # } # } # # nested_hash.berks_dig('deep.nested.hash') => :seed_value # # @param [String] path # # @return [Object, nil] def berks_dig(path) return nil unless path.present? parts = path.split('.', 2) match = self[parts[0].to_s].nil? ? self[parts[0].to_sym] : self[parts[0].to_s] if !parts[1] or match.nil? match else match.berks_dig(parts[1]) end end # Returns an array of dotted paths from the keys, values of this Hash. Values which are # nested Hashes will also recurred into and their paths will be added properly. # # @param [Hash] source # @param [Array] acc # @param [Array] namespace # # @return [Array] def dotted_paths(source = self, acc = Array.new, namespace = Array.new) if source.is_a?(Hash) && !source.empty? source.each do |key, value| branch = namespace.dup branch << key dotted_paths(value, acc, branch) end else acc << namespace.join('.') end acc end end end end class Hash include Buff::Extensions::Hash::DottedPaths end buff-extensions-2.0.0/lib/buff/extensions/hash/except.rb0000644000004100000410000000127212754217533023322 0ustar www-datawww-datamodule Buff module Extensions::Hash # Borrowd and modified from # {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/except.rb} module Except # Return a hash that includes everything but the given keys. This is useful for # limiting a set of parameters to everything but a few known toggles: # # @person.update(params[:person].except(:admin)) def except(*keys) dup.except!(*keys) end # Replaces the hash without the given keys. def except!(*keys) keys.each { |key| delete(key) } self end end end end class Hash include Buff::Extensions::Hash::Except end buff-extensions-2.0.0/lib/buff/extensions/hash/key_transforms.rb0000644000004100000410000001205512754217533025101 0ustar www-datawww-datamodule Buff module Extensions::Hash # Borrowd and modified from # {https://raw.github.com/rails/rails/master/activesupport/lib/active_support/core_ext/hash/keys.rb} module KeyTransforms # Return a new hash with all keys converted using the block operation. # # hash = { name: 'Rob', age: '28' } # # hash.transform_keys{ |key| key.to_s.upcase } # # => { "NAME" => "Rob", "AGE" => "28" } def transform_keys result = {} each_key do |key| result[yield(key)] = self[key] end result end # Destructively convert all keys using the block operations. # Same as transform_keys but modifies +self+. def transform_keys! keys.each do |key| self[yield(key)] = delete(key) end self end # Return a new hash with all keys converted to strings. # # hash = { name: 'Rob', age: '28' } # # hash.stringify_keys # #=> { "name" => "Rob", "age" => "28" } def stringify_keys transform_keys { |key| key.to_s } end # Destructively convert all keys to strings. Same as # +stringify_keys+, but modifies +self+. def stringify_keys! transform_keys! { |key| key.to_s } end # Return a new hash with all keys converted to symbols, as long as # they respond to +to_sym+. # # hash = { 'name' => 'Rob', 'age' => '28' } # # hash.symbolize_keys # #=> { name: "Rob", age: "28" } def symbolize_keys transform_keys { |key| key.to_sym rescue key } end alias_method :to_options, :symbolize_keys # Destructively convert all keys to symbols, as long as they respond # to +to_sym+. Same as +symbolize_keys+, but modifies +self+. def symbolize_keys! transform_keys! { |key| key.to_sym rescue key } end alias_method :to_options!, :symbolize_keys! # Validate all keys in a hash match *valid_keys, raising ArgumentError # on a mismatch. Note that keys are NOT treated indifferently, meaning if you # use strings for keys but assert symbols as keys, this will fail. # # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years" # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name" # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing def assert_valid_keys(*valid_keys) valid_keys.flatten! each_key do |k| raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k) end end # Return a new hash with all keys converted by the block operation. # This includes the keys from the root hash and from all # nested hashes. # # hash = { person: { name: 'Rob', age: '28' } } # # hash.deep_transform_keys{ |key| key.to_s.upcase } # # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } } def deep_transform_keys(&block) result = {} each do |key, value| result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value end result end # Destructively convert all keys by using the block operation. # This includes the keys from the root hash and from all # nested hashes. def deep_transform_keys!(&block) keys.each do |key| value = delete(key) self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value end self end # Return a new hash with all keys converted to strings. # This includes the keys from the root hash and from all # nested hashes. # # hash = { person: { name: 'Rob', age: '28' } } # # hash.deep_stringify_keys # # => { "person" => { "name" => "Rob", "age" => "28" } } def deep_stringify_keys deep_transform_keys { |key| key.to_s } end # Destructively convert all keys to strings. # This includes the keys from the root hash and from all # nested hashes. def deep_stringify_keys! deep_transform_keys! { |key| key.to_s } end # Return a new hash with all keys converted to symbols, as long as # they respond to +to_sym+. This includes the keys from the root hash # and from all nested hashes. # # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } # # hash.deep_symbolize_keys # # => { person: { name: "Rob", age: "28" } } def deep_symbolize_keys deep_transform_keys { |key| key.to_sym rescue key } end # Destructively convert all keys to symbols, as long as they respond # to +to_sym+. This includes the keys from the root hash and from all # nested hashes. def deep_symbolize_keys! deep_transform_keys! { |key| key.to_sym rescue key } end end end end class Hash include Buff::Extensions::Hash::KeyTransforms end buff-extensions-2.0.0/lib/buff/extensions/hash/slice.rb0000644000004100000410000000337512754217533023137 0ustar www-datawww-datamodule Buff module Extensions::Hash # Borrowd and modified from # {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/slice.rb} module Slice # Slice a hash to include only the given keys. This is useful for # limiting an options hash to valid keys before passing to a method: # # def search(criteria = {}) # criteria.assert_valid_keys(:mass, :velocity, :time) # end # # search(options.slice(:mass, :velocity, :time)) # # If you have an array of keys you want to limit to, you should splat them: # # valid_keys = [:mass, :velocity, :time] # search(options.slice(*valid_keys)) def slice(*keys) keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) } end # Replaces the hash with only the given keys. # Returns a hash containing the removed key/value pairs. # # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b) # # => {:c=>3, :d=>4} def slice!(*keys) keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) omit = slice(*self.keys - keys) hash = slice(*keys) replace(hash) omit end # Removes and returns the key/value pairs matching the given keys. # # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2} # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1} def extract!(*keys) keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) } end end end end class Hash include Buff::Extensions::Hash::Slice end buff-extensions-2.0.0/lib/buff/extensions/boolean.rb0000644000004100000410000000020112754217533022515 0ustar www-datawww-datamodule Buff module Boolean; end end class TrueClass include Buff::Boolean end class FalseClass include Buff::Boolean end buff-extensions-2.0.0/lib/buff/extensions/version.rb0000644000004100000410000000010012754217533022561 0ustar www-datawww-datamodule Buff module Extensions VERSION = "2.0.0" end end buff-extensions-2.0.0/lib/buff/extensions/kernel/0000755000004100000410000000000012754217533022040 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions/kernel/reporting.rb0000644000004100000410000000635212754217533024404 0ustar www-datawww-datarequire 'rbconfig' require 'tempfile' module Buff module Extensions::Kernel # Borrowd and modified from # {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/kernel/reporting.rb} module Reporting # Sets $VERBOSE to nil for the duration of the block and back to its original # value afterwards. # # silence_warnings do # value = noisy_call # no warning voiced # end # # noisy_call # warning voiced def silence_warnings with_warnings(nil) { yield } end # Sets $VERBOSE to +true+ for the duration of the block and back to its # original value afterwards. def enable_warnings with_warnings(true) { yield } end # Sets $VERBOSE for the duration of the block and back to its original # value afterwards. def with_warnings(flag) old_verbose, $VERBOSE = $VERBOSE, flag yield ensure $VERBOSE = old_verbose end # For compatibility def silence_stderr #:nodoc: silence_stream(STDERR) { yield } end # Silences any stream for the duration of the block. # # silence_stream(STDOUT) do # puts 'This will never be seen' # end # # puts 'But this will' def silence_stream(stream) old_stream = stream.dup stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null') stream.sync = true yield ensure stream.reopen(old_stream) end # Blocks and ignores any exception passed as argument if raised within the block. # # suppress(ZeroDivisionError) do # 1/0 # puts 'This code is NOT reached' # end # # puts 'This code gets executed and nothing related to ZeroDivisionError was seen' def suppress(*exception_classes) yield rescue Exception => e raise unless exception_classes.any? { |cls| e.kind_of?(cls) } end # Captures the given stream and returns it: # # stream = capture(:stdout) { puts 'notice' } # stream # => "notice\n" # # stream = capture(:stderr) { warn 'error' } # stream # => "error\n" # # even for subprocesses: # # stream = capture(:stdout) { system('echo notice') } # stream # => "notice\n" # # stream = capture(:stderr) { system('echo error 1>&2') } # stream # => "error\n" def capture(stream) stream = stream.to_s captured_stream = Tempfile.new(stream) stream_io = eval("$#{stream}") origin_stream = stream_io.dup stream_io.reopen(captured_stream) yield stream_io.rewind return captured_stream.read ensure captured_stream.unlink stream_io.reopen(origin_stream) end alias :silence :capture # Silences both STDOUT and STDERR, even for subprocesses. # # quietly { system 'bundle install' } def quietly silence_stream(STDOUT) do silence_stream(STDERR) do yield end end end end end end module Kernel include Buff::Extensions::Kernel::Reporting end buff-extensions-2.0.0/lib/buff/extensions/string/0000755000004100000410000000000012754217533022066 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions/string/inflections.rb0000644000004100000410000000075712754217533024741 0ustar www-datawww-datamodule Buff module Extensions::String module Inflections def underscore word = self.dup word.gsub!('::', '/') word.gsub!(/(?:([A-Za-z\d])|^)((?=a)b)(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end end end end class String include Buff::Extensions::String::Inflections end buff-extensions-2.0.0/lib/buff/extensions/kernel.rb0000644000004100000410000000017212754217533022365 0ustar www-datawww-datarequire_relative 'kernel/reporting' class Object # Re-include since the Kernel module was altered include Kernel end buff-extensions-2.0.0/lib/buff/extensions/object/0000755000004100000410000000000012754217533022026 5ustar www-datawww-databuff-extensions-2.0.0/lib/buff/extensions/object/blank.rb0000644000004100000410000000434112754217533023444 0ustar www-datawww-data# Borrowed and modified from # {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb} class Object # An object is blank if it's false, empty, or a whitespace string. # For example, '', ' ', +nil+, [], and {} are all blank. # # This simplifies: # # if address.nil? || address.empty? # # ...to: # # if address.blank? def blank? respond_to?(:empty?) ? empty? : !self end # An object is present if it's not blank?. def present? !blank? end # Returns object if it's present? otherwise returns +nil+. # object.presence is equivalent to object.present? ? object : nil. # # This is handy for any representation of objects where blank is the same # as not present at all. For example, this simplifies a common check for # HTTP POST/query parameters: # # state = params[:state] if params[:state].present? # country = params[:country] if params[:country].present? # region = state || country || 'US' # # ...becomes: # # region = params[:state].presence || params[:country].presence || 'US' def presence self if present? end end class NilClass # +nil+ is blank: # # nil.blank? # => true def blank? true end end class FalseClass # +false+ is blank: # # false.blank? # => true def blank? true end end class TrueClass # +true+ is not blank: # # true.blank? # => false def blank? false end end class Array # An array is blank if it's empty: # # [].blank? # => true # [1,2,3].blank? # => false alias_method :blank?, :empty? end class Hash # A hash is blank if it's empty: # # {}.blank? # => true # { key: 'value' }.blank? # => false alias_method :blank?, :empty? end class String # A string is blank if it's empty or contains whitespaces only: # # ''.blank? # => true # ' '.blank? # => true # ' '.blank? # => true # ' something here '.blank? # => false def blank? self !~ /[^[:space:]]/ end end class Numeric #:nodoc: # No number is blank: # # 1.blank? # => false # 0.blank? # => false def blank? false end end buff-extensions-2.0.0/lib/buff/extensions/object/try.rb0000644000004100000410000000435112754217533023174 0ustar www-datawww-data# Borrowed and modified from # {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/try.rb} class Object # Invokes the public method whose name goes as first argument just like # +public_send+ does, except that if the receiver does not respond to it the # call returns +nil+ rather than raising an exception. # # This method is defined to be able to write # # @person.try(:name) # # instead of # # @person ? @person.name : nil # # +try+ returns +nil+ when called on +nil+ regardless of whether it responds # to the method: # # nil.try(:to_i) # => nil, rather than 0 # # Arguments and blocks are forwarded to the method if invoked: # # @posts.try(:each_slice, 2) do |a, b| # ... # end # # The number of arguments in the signature must match. If the object responds # to the method the call is attempted and +ArgumentError+ is still raised # otherwise. # # If +try+ is called without arguments it yields the receiver to a given # block unless it is +nil+: # # @person.try do |p| # ... # end # # Please also note that +try+ is defined on +Object+, therefore it won't work # with instances of classes that do not have +Object+ among their ancestors, # like direct subclasses of +BasicObject+. For example, using +try+ with # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on # delegator itself. def try(*a, &b) if a.empty? && block_given? yield self else public_send(*a, &b) if respond_to?(a.first) end end # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and # does not implemented the tried method. def try!(*a, &b) if a.empty? && block_given? yield self else public_send(*a, &b) end end end class NilClass # Calling +try+ on +nil+ always returns +nil+. # It becomes specially helpful when navigating through associations that may return +nil+. # # nil.try(:name) # => nil # # Without +try+ # @person && !@person.children.blank? && @person.children.first.name # # With +try+ # @person.try(:children).try(:first).try(:name) def try(*args) nil end def try!(*args) nil end end buff-extensions-2.0.0/lib/buff-extensions.rb0000644000004100000410000000004312754217533021100 0ustar www-datawww-datarequire_relative 'buff/extensions' buff-extensions-2.0.0/.gitignore0000644000004100000410000000023212754217533016656 0ustar www-datawww-data*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp buff-extensions-2.0.0/CONTRIBUTING.md0000644000004100000410000000067512754217533017132 0ustar www-datawww-data# Contributing ## Running tests ### Install prerequisites Install the latest version of [Bundler](http://gembundler.com) $ gem install bundler Clone the project $ git clone git://github.com/RiotGames/buff-extensions.git and run: $ cd buff-extensions $ bundle install Bundler will install all gems and their dependencies required for testing and developing. ### Running unit (RSpec) tests $ bundle exec guard start buff-extensions-2.0.0/LICENSE0000644000004100000410000000113012754217533015671 0ustar www-datawww-dataCopyright 2012-2013 Riot Games Jamie Winsor () Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. buff-extensions-2.0.0/README.md0000644000004100000410000000145012754217533016150 0ustar www-datawww-data# Buff::Extensions [![Gem Version](https://badge.fury.io/rb/buff-extensions.png)](http://badge.fury.io/rb/buff-extensions) [![Build Status](https://travis-ci.org/RiotGames/buff-extensions.png?branch=master)](https://travis-ci.org/RiotGames/buff-extensions) Extensions to Core Ruby classes ## Installation Add this line to your application's Gemfile: gem 'buff-extensions' And then execute: $ bundle Or install it yourself as: $ gem install buff-extensions ## Usage Using it as a mixin require 'buff/extensions' class PowerHash include Buff::Extensions::DottedPaths end # Authors and Contributors * Jamie Winsor () Thank you to all of our [Contributors](https://github.com/RiotGames/buff-extensions/graphs/contributors), testers, and users. buff-extensions-2.0.0/Guardfile0000644000004100000410000000070412754217533016517 0ustar www-datawww-datanotification :off guard "spork" do watch('Gemfile') watch('spec/spec_helper.rb') { :rspec } watch(%r{^spec/support/.+\.rb$}) { :rspec } end guard "rspec", cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } watch(%r{^spec/support/.+\.rb$}) { "spec" } end