Skip to content

Instantly share code, notes, and snippets.

@hartator
Created July 27, 2015 17:43
Show Gist options
  • Save hartator/f03ad87972c4f40ede7a to your computer and use it in GitHub Desktop.
Save hartator/f03ad87972c4f40ede7a to your computer and use it in GitHub Desktop.
module DeepFetch
def deep_fetch(*keys, &fetch_default)
throw_fetch_default = fetch_default && lambda {|key, coll|
args = [key, coll]
# only provide extra block args if requested
args = args.slice(0, fetch_default.arity) if fetch_default.arity >= 0
# If we need the default, we need to stop processing the loop immediately
throw :df_value, fetch_default.call(*args)
}
catch(:df_value){
keys.inject(self){|value,key|
block = throw_fetch_default && lambda{|*args|
# sneak the current collection in as an extra block arg
args < < value
throw_fetch_default.call(*args)
}
value.fetch(key, &block)
}
}
end
# Overload [] to work with multiple keys
def [](*keys)
case keys.size
when 1 then super
else deep_fetch(*keys){|key, coll| coll[key]}
end
end
end
params.extend(DeepFetch)
if params[:user, :remember_me]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment