lib/pa/util.rb in pa-1.3.0 vs lib/pa/util.rb in pa-1.3.1

- old
+ new

@@ -1,41 +1,138 @@ +require "rbconfig" + class Pa + # In order to reduce the dependencies, this Util class contains some util functions. class Util module Concern def included(base) base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) - base.send :include, const_get(:InstanceMethods) if const_defined?(:InstanceMethods) end end class << self - # extract options - # @see extract_options! + # Extracts options from a set of arguments. + # # @example - # def mkdir(*args) - # paths, o = args.extract_options - # end # + # dirs, o = Util.extract_options(["foo", "bar", {a: 1}], b: 2) + # -> ["foo", "bar"], {a: 1, b: 2} + # + # (dir,) o = Util.extract_options(["foo", {a: 1}]) + # -> "foo", {a: 1} + # # @return [Array<Array,Hash>] - def extract_options(ary, default={}) - if ary.last.is_a?(Hash) && ary.last.instance_of?(Hash) - [ary[0...-1], ary[-1].merge(default)] + def extract_options(args, default={}) + if args.last.instance_of?(Hash) + [args[0...-1], default.merge(args[-1])] else - [ary, default] + [args, default] end end - def wrap_array(value) - Array === value ? value : [value] + # Wraps its argument in an array unless it is already an array (or array-like). + # + # Specifically: + # + # * If the argument is +nil+ an empty list is returned. + # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned. + # * Otherwise, returns an array with the argument as its single element. + # + # Array.wrap(nil) # => [] + # Array.wrap([1, 2, 3]) # => [1, 2, 3] + # Array.wrap(0) # => [0] + # + # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences: + # + # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> + # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns + # such a +nil+ right away. + # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> + # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value. + # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array. + # + # The last point is particularly worth comparing for some enumerables: + # + # Array(:foo => :bar) # => [[:foo, :bar]] + # Array.wrap(:foo => :bar) # => [{:foo => :bar}] + # + # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8 + # Array.wrap("foo\nbar") # => ["foo\nbar"] + # + # There's also a related idiom that uses the splat operator: + # + # [*object] + # + # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise. + # + # Thus, in this case the behavior is different for +nil+, and the differences with + # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s. + def wrap_array(object) + if object.nil? + [] + elsif object.respond_to?(:to_ary) + object.to_ary || [object] + else + [object] + end end - def win32? - RUBY_PLATFORM =~ /mingw32|mswin/ - end + # 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: + # + # @example + # + # a = {a: 1, b: 2, c: 3} + # a.slaice(:a, :b) -> {a: 1, b: 2} + def slice(hash, *keys) + keys = keys.map! { |key| hash.convert_key(key) } if hash.respond_to?(:convert_key) + h = hash.class.new + keys.each { |k| h[k] = hash[k] if hash.has_key?(k) } + h + end - # join(".", "foo") => "foo" not "./foo" - def join(dir, *names) + # different to File.join. + # + # @example + # + # join_path(".", "foo") -> "foo" not "./foo" + # + def join_path(dir, *names) dir == "." ? File.join(*names) : File.join(dir, *names) + end + + def linux? + RbConfig::CONFIG["host_os"] =~ /linux|cygwin/ + end + + def mac? + RbConfig::CONFIG["host_os"] =~ /mac|darwin/ + end + + def bsd? + RbConfig::CONFIG["host_os"] =~ /bsd/ + end + + def windows? + RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ + end + + def solaris? + RbConfig::CONFIG["host_os"] =~ /solaris|sunos/ + end + + # TODO: who knows what symbian returns? + def symbian? + RbConfig::CONFIG["host_os"] =~ /symbian/ + end + + def posix? + linux? or mac? or bsd? or solaris? or begin + fork do end + true + rescue NotImplementedError, NoMethodError + false + end end end end end