ruby - Generating configuration hash with reduce in the Jekyll source code? -
i've been looking through jekyll source code, , stumbled upon method:
# public: generate jekyll configuration hash merging default # options in _config.yml, , adding given options on top. # # override - hash of config directives override options in both # defaults , config file. see jekyll::defaults # list of option names , defaults. # # returns final configuration hash. def self.configuration(override) # convert symbol keys strings , remove old key/values override = override.reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) } # _config.yml may override default source location, until # then, need know _config.yml source = override['source'] || jekyll::defaults['source'] # configuration <source>/_config.yml or <source>/<config_file> config_file = override.delete('config') config_file = file.join(source, "_config.yml") if config_file.to_s.empty? begin config = yaml.safe_load_file(config_file) raise "configuration file: (invalid) #{config_file}" if !config.is_a?(hash) $stdout.puts "configuration file: #{config_file}" rescue systemcallerror # errno:enoent = file not found $stderr.puts "configuration file: none" config = {} rescue => err $stderr.puts " " + "warning: error reading configuration. " + "using defaults (and options)." $stderr.puts "#{err}" config = {} end # merge defaults < _config.yml < override jekyll::defaults.deep_merge(config).deep_merge(override) end end
i can't figure out despite comments. reduce({})
bothers me - do?
also, method called before configuration
is:
options = normalize_options(options.__hash__)
what __hash__
do?
let's @ code in question:
override.reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
now let's @ docs enumerable#reduce
:
combines elements of enum applying binary operation, specified block or symbol names method or operator.
if specify block, each element in enum block passed accumulator value (memo) , element. if specify symbol instead, each element in collection passed named method of memo. in either case, result becomes new value memo. @ end of iteration, final value of memo return value method.
so, override going typical ruby options hash, like:
{ debug: 'true', awesomeness: 'maximum' }
so happens when use reduce
on override?
it combine elements of enum (key => value pairs of override hash) using binary function merge
. merge takes hash , merges receiver. what's happening here?
hsh
starts out{}
, first key/value pair merged:{}.merge(:debug.to_s => "true")
.hsh
{"debug" => "true"}
.- the next key/value pair merged that:
{"debug" => "true"}.merge(:awesomeness.to_s => "maximum")
. hsh
{"debug" => "true", "awesomeness" => "maximum"}
- there no more elements, value of
hsh
returned.
this matches code comment, says "convert symbol keys strings , remove old key/values", although technically old values not removed. rather, new hash constructed , old hash old values discarded replacing variable new value, collected – along intermediate objects created merges in reduce – garbage collector. aside, means merge!
more efficient merge
in case not create intermediate objects.
__foo__
ruby idiom quasi-private and/or 'core' method want make sure isn't redefined, e.g., __send__
because things socket
want use send
. in ruby, hash
hash value of object (computed using hash function, used when object used hash key), __hash__
points instance variable of options
object stores data hash. here's class gem that. you'd have @ docs whatever type of object options
sure though. (you'd have @ code really sure. ;)
Comments
Post a Comment