lib/jsi/util.rb in jsi-0.2.1 vs lib/jsi/util.rb in jsi-0.3.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + module JSI module Util # a proc which does nothing NOOP = -> (*_) { } @@ -15,72 +17,48 @@ # argument instance. # # @param hash [#to_hash] the hash from which to convert symbol keys to strings # @return [same class as the param `hash`, or Hash if the former cannot be done] a # hash(-like) instance containing no symbol keys - def stringify_symbol_keys(hash) - unless hash.respond_to?(:to_hash) - raise(ArgumentError, "expected argument to be a hash; got #{hash.class.inspect}: #{hash.pretty_inspect.chomp}") + def stringify_symbol_keys(hashlike) + unless hashlike.respond_to?(:to_hash) + raise(ArgumentError, "expected argument to be a hash; got #{hashlike.class.inspect}: #{hashlike.pretty_inspect.chomp}") end - JSI::Typelike.modified_copy(hash) do |hash_| - changed = false + JSI::Typelike.modified_copy(hashlike) do |hash| out = {} - hash_.each do |k, v| - if k.is_a?(Symbol) - changed = true - k = k.to_s - end - out[k] = v + hash.each do |k, v| + out[k.is_a?(Symbol) ? k.to_s : k] = v end - changed ? out : hash_ + out end end def deep_stringify_symbol_keys(object) if object.respond_to?(:to_hash) JSI::Typelike.modified_copy(object) do |hash| - changed = false out = {} (hash.respond_to?(:each) ? hash : hash.to_hash).each do |k, v| - if k.is_a?(Symbol) - changed = true - k = k.to_s - end - out_k = deep_stringify_symbol_keys(k) - out_v = deep_stringify_symbol_keys(v) - changed = true if out_k.object_id != k.object_id - changed = true if out_v.object_id != v.object_id - out[out_k] = out_v + out[k.is_a?(Symbol) ? k.to_s : deep_stringify_symbol_keys(k)] = deep_stringify_symbol_keys(v) end - changed ? out : hash + out end elsif object.respond_to?(:to_ary) JSI::Typelike.modified_copy(object) do |ary| - changed = false - out = (ary.respond_to?(:each) ? ary : ary.to_ary).map do |e| - out_e = deep_stringify_symbol_keys(e) - changed = true if out_e.object_id != e.object_id - out_e + (ary.respond_to?(:each) ? ary : ary.to_ary).map do |e| + deep_stringify_symbol_keys(e) end - changed ? out : ary end else object end end - # @param object_group_text [Array<String>] - # @return [String] - def object_group_str(object_group_text) - object_group_text.compact.map { |t| " #{t}" }.join('') - end - # this is the Y-combinator, which allows anonymous recursive functions. for a simple example, # to define a recursive function to return the length of an array: # # length = ycomb do |len| - # proc{|list| list == [] ? 0 : 1 + len.call(list[1..-1]) } + # proc { |list| list == [] ? 0 : 1 + len.call(list[1..-1]) } # end # # see https://secure.wikimedia.org/wikipedia/en/wiki/Fixed_point_combinator#Y_combinator # and chapter 9 of the little schemer, available as the sample chapter at http://www.ccs.neu.edu/home/matthias/BTLS/ def ycomb @@ -90,36 +68,38 @@ end public extend Util module FingerprintHash + # overrides BasicObject#== def ==(other) - object_id == other.object_id || (other.respond_to?(:fingerprint) && other.fingerprint == self.fingerprint) + object_id == other.object_id || (other.respond_to?(:jsi_fingerprint) && other.jsi_fingerprint == self.jsi_fingerprint) end alias_method :eql?, :== + # overrides Kernel#hash def hash - fingerprint.hash + jsi_fingerprint.hash end end module Memoize - def memoize(key, *args_) - @memos ||= {} - @memos[key] ||= Hash.new do |h, args| + def jsi_memoize(key, *args_) + @jsi_memos ||= {} + @jsi_memos[key] ||= Hash.new do |h, args| h[args] = yield(*args) end - @memos[key][args_] + @jsi_memos[key][args_] end - def clear_memo(key, *args) - @memos ||= {} - if @memos[key] + def jsi_clear_memo(key, *args) + @jsi_memos ||= {} + if @jsi_memos[key] if args.empty? - @memos[key].clear + @jsi_memos[key].clear else - @memos[key].delete(args) + @jsi_memos[key].delete(args) end end end end extend Memoize