OSDN Git Service

Fix test failures related to MAX_MOVES and least time per move
[shogi-server/shogi-server.git] / shogi_server / config.rb
1 #--
2 # Copyright (c) 2006-2009 by Craig P Jolicoeur <cpjolicoeur at gmail dot com>
3 # Copyright (C) 2009-2012 Daigo Moriwaki <daigo at debian dot org>
4
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #++
24
25 #
26 # This code was copied from cerberus[1] and modified.
27 # [1] http://rubyforge.org/projects/cerberus
28 #
29
30 require 'erb'
31
32 class Hash
33   def deep_merge!(second)
34     second.each_pair do |k,v|
35       if self[k].is_a?(Hash) && second[k].is_a?(Hash)
36         self[k].deep_merge!(second[k])
37       else
38         self[k] = second[k]
39       end
40     end
41   end
42 end
43
44 class HashWithIndifferentAccess < Hash
45   def initialize(constructor = {})
46     if constructor.is_a?(Hash)
47       super()
48       update(constructor)
49     else
50       super(constructor)
51     end
52   end
53  
54   def default(key)
55     self[key.to_s] if key.is_a?(Symbol)
56   end  
57
58   alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
59   alias_method :regular_update, :update unless method_defined?(:regular_update)
60   
61   def []=(key, value)
62     regular_writer(convert_key(key), convert_value(value))
63   end
64
65   def update(other_hash)
66     other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
67     self
68   end
69   
70   alias_method :merge!, :update
71
72   def key?(key)
73     super(convert_key(key))
74   end
75
76   alias_method :include?, :key?
77   alias_method :has_key?, :key?
78   alias_method :member?, :key?
79
80   def fetch(key, *extras)
81     super(convert_key(key), *extras)
82   end
83
84   def values_at(*indices)
85     indices.collect {|key| self[convert_key(key)]}
86   end
87
88   def dup
89     HashWithIndifferentAccess.new(self)
90   end
91   
92   def merge(hash)
93     self.dup.update(hash)
94   end
95
96   def delete(key)
97     super(convert_key(key))
98   end
99     
100   protected
101     def convert_key(key)
102       key.kind_of?(Symbol) ? key.to_s : key
103     end
104     def convert_value(value)
105       value.is_a?(Hash) ? HashWithIndifferentAccess.new(value) : value
106     end
107 end
108
109
110 module ShogiServer
111   class Config
112     FILENAME = 'shogi-server.yaml'
113
114     def initialize(options = {})
115       @config = HashWithIndifferentAccess.new
116       
117       if options.is_a?(Hash)
118         options[:topdir] ||= $topdir if $topdir
119         options[:topdir] ||= options["topdir"] if options["topdir"]
120       end
121
122       if options[:topdir] && File.exist?(File.join(options[:topdir], FILENAME))
123         merge!(YAML.load(ERB.new(IO.read(File.join(options[:topdir], FILENAME)).result)))
124       end
125
126       merge!(options)
127     end
128
129     def [](*path)
130       c = @config
131       path.each{|p|
132         c = c[p]
133         return if c.nil?
134       }
135       c
136     end
137
138     def merge!(hash, overwrite = true)
139       return unless hash && !hash.empty?
140       if overwrite
141         @config.deep_merge!(hash)
142       else
143         d = HashWithIndifferentAccess.new(hash)
144         d.deep_merge!(@config)
145         @config = d
146       end
147     end
148
149     def inspect
150       @config.inspect
151     end
152
153     private
154     def symbolize_hash(hash)
155       hash.each_pair{|k,v|
156         if v === Hash
157           hash[k] = HashWithIndifferentAccess.new(symbolize_hash(v))
158         end
159       }
160     end
161   end
162 end # module ShogiServer