lib/ruby-conf.rb in ruby-conf-2.7.2 vs lib/ruby-conf.rb in ruby-conf-2.8.0

- old
+ new

@@ -71,11 +71,11 @@ attr_accessor :__rc_chain def __rc_gather() "#{to_s}#{__rc_chain.nil? ? "" : " #{__rc_chain.__rc_gather}"}" end end class Config - attr_reader :__rc_attributes, :__rc_parent, :__rc_name, :__rc_chains, :__rc_locked + attr_reader :__rc_attributes, :__rc_parent, :__rc_name, :__rc_chains, :__rc_locked, :__rc_static_values def __rc_root() __rc_parent ? __rc_parent.__rc_root : self end def detach(parent = nil) @__rc_parent = parent @__rc_attributes.values.each do |child| @@ -83,11 +83,11 @@ end self end def initialize(name = nil, parent = nil, &block) - @__rc_locked, @__rc_attributes, @__rc_chains, @__rc_parent = false, {}, [], parent + @__rc_locked, @__rc_attributes, @__rc_chains, @__rc_parent, @__rc_static_values = false, {}, [], parent, {} @__rc_name = name.to_sym if name instance_eval(&block) if block_given? __rc_lock end @@ -95,10 +95,16 @@ @__rc_locked = true @__rc_attributes.each_value { |value| value.__rc_lock if value.is_a?(Config) } self end + def __rc_static_proc(name, *args) + name = name.to_sym + static_key = "#{name}:#{args}" + @__rc_static_values[static_key] || self[name, *args] + end + def [](name, *args) name = name.to_sym value = @__rc_attributes[name] if value.is_a?(Proc) args += [nil] * (value.arity.abs - args.size) if value.arity.abs > args.size @@ -107,11 +113,14 @@ RubyConf.err("[ruby-conf] Detected recursive proc: #{name}") "[RECURSIVE]" else @@stack << name begin - __rc_root.instance_exec(*args, &value) + value = __rc_root.instance_exec(*args, &value) + static_key = "#{name}:#{args}" + @__rc_static_values[static_key] = value + value ensure @@stack.delete(name) end end else @@ -196,14 +205,27 @@ @__rc_chains << str return str end if args.empty? - modifier == '?' ? !!self[name] : self[name] + if modifier == '?' + !!self[name] + elsif modifier == '!' && __rc_attributes[name.to_sym].is_a?(Proc) + __rc_static_proc(name) + else + self[name] + end else arg = args.size == 1 ? args.first : args - - (@__rc_locked && __rc_attributes[name.to_sym].is_a?(Proc)) ? self[name, *args] : self[name] = arg + if @__rc_locked && __rc_attributes[name.to_sym].is_a?(Proc) + if modifier == '!' + __rc_static_proc(name, *args) + else + self[name, *args] + end + else + self[name] = arg + end end end end def respond_to?(name)