From: Nobuyoshi Nakada Date: 2010-05-04T16:35:59+09:00 Subject: [ruby-core:29993] [Feature:trunk] thread-local yamler Hi, Currently, YAML.yamler= has an effect on the whole process. What about making it thread-local? diff --git a/lib/yaml.rb b/lib/yaml.rb index 9b5a9b2..236489b 100644 --- a/lib/yaml.rb +++ b/lib/yaml.rb @@ -1,43 +1,68 @@ module YAML - class EngineManager # :nodoc: - attr_reader :yamler + class << self + def engine + ::Thread.current[:yamler] or + (ENGINE.yamler = ENGINE.default; ::Thread.current[:yamler]) + end - def initialize - @yamler = nil + def const_defined?(name) + engine.const_defined?(name) end - def syck? - 'syck' == @yamler + def const_get(name) + engine = self.engine + begin + engine.const_get(name) + rescue NameError => e + raise NameError, "uninitialized constant #{self}::#{name}", caller(2) + end end - def yamler= engine - raise(ArgumentError, "bad engine") unless %w{syck psych}.include?(engine) + alias const_missing const_get - require engine + def method_missing(name, *args, &block) + engine.__send__(name, *args, &block) + end - Object.class_eval <<-eorb, __FILE__, __LINE__ + 1 - remove_const 'YAML' - YAML = #{engine.capitalize} - remove_method :to_yaml - alias :to_yaml :#{engine}_to_yaml - eorb + def respond_to_missing?(name) + engine.respond_to?(name) + end + + private + + def extend_object(obj) + engine.__send__(:extend_object, obj) + end - @yamler = engine - engine + def append_features(mod) + engine.__send__(:append_features, mod) end end - ENGINE = YAML::EngineManager.new -end + class << (ENGINE = Object.new) # :nodoc: + def default + !defined?(Syck) && defined?(Psych) ? 'psych' : 'syck' + end -engine = (!defined?(Syck) && defined?(Psych) ? 'psych' : 'syck') + def yamler + if engine = YAML.engine + engine.name.downcase + else + default + end + end -module Syck - ENGINE = YAML::ENGINE -end + def syck? + 'syck' == yamler + end -module Psych - ENGINE = YAML::ENGINE -end + def yamler= engine + raise(ArgumentError, "bad engine") unless %w{syck psych}.include?(engine) + require engine + engine = ::Object.const_get(engine.capitalize) + ::Thread.current[:yamler] = engine + end + end -YAML::ENGINE.yamler = engine + ENGINE.freeze +end -- Nobu Nakada