moduleHashiemoduleExtensionsmoduleDeepLocate# The module level implementation of #deep_locate, incase you do not want# to include/extend the base datastructure. For further examples please# see #deep_locate.## @example# books = [# {# title: "Ruby for beginners",# pages: 120# },# ...# ]## Hashie::Extensions::DeepLocate.deep_locate -> (key, value, object) { key == :title }, books# # => [{:title=>"Ruby for beginners", :pages=>120}, ...]defself.deep_locate(comparator,object)comparator=_construct_key_comparator(comparator,object)unlesscomparator.respond_to?(:call)_deep_locate(comparator,object)end# Performs a depth-first search on deeply nested data structures for a# given comparator callable and returns each Enumerable, for which the# callable returns true for at least one the its elements.## @example# books = [# {# title: "Ruby for beginners",# pages: 120# },# {# title: "CSS for intermediates",# pages: 80# },# {# title: "Collection of ruby books",# books: [# {# title: "Ruby for the rest of us",# pages: 576# }# ]# }# ]## books.extend(Hashie::Extensions::DeepLocate)## # for ruby 1.9 leave *no* space between the lambda rocket and the braces# # http://ruby-journal.com/becareful-with-space-in-lambda-hash-rocket-syntax-between-ruby-1-dot-9-and-2-dot-0/## books.deep_locate -> (key, value, object) { key == :title && value.include?("Ruby") }# # => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"Ruby for the rest of us", :pages=>576}]## books.deep_locate -> (key, value, object) { key == :pages && value <= 120 }# # => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"CSS for intermediates", :pages=>80}]defdeep_locate(comparator)Hashie::Extensions::DeepLocate.deep_locate(comparator,self)endprivatedefself._construct_key_comparator(search_key,object)search_key=search_key.to_sifdefined?(::ActiveSupport::HashWithIndifferentAccess)&&object.is_a?(::ActiveSupport::HashWithIndifferentAccess)search_key=search_key.to_sifobject.respond_to?(:indifferent_access?)&&object.indifferent_access?lambdado|non_callable_object|->(key,_,_){key==non_callable_object}end.call(search_key)enddefself._deep_locate(comparator,object,result=[])ifobject.is_a?(::Enumerable)ifobject.any?{|value|_match_comparator?(value,comparator,object)}result.pushobjectend(object.respond_to?(:values)?object.values:object.entries).eachdo|value|_deep_locate(comparator,value,result)endendresultenddefself._match_comparator?(value,comparator,object)ifobject.is_a?(::Hash)key,value=valueelsekey=nilendcomparator.call(key,value,object)endendendend