Permalink
Browse files

optimise the code :)

  • Loading branch information...
1 parent 7c152a8 commit b788d3c077cd73b14f487f04f789587be68e126e @gutenye committed Aug 21, 2012
View
15 CHANGELOG
@@ -0,0 +1,15 @@
+*Optimism (3.3.0)*
+
+ * remove 'Optimism.get', 'Optimsm.convert', 'Optimims.[]', 'Optimism#_get', 'Optimism#_child'
+ * remove 'hike' dependency
+ * add 'Optimism.require!', 'Optimism#_has_key2?'
+ * 'Optimism#initialize'
+ - add (hash/optimism, o)
+ - rename ':only_symbol_key' option to ':symbolize_key'
+ - add ':parser' option
+ * 'Optimism.require'
+ - support yaml file (.yml)
+ - rename ':mixin' option to ':merge'
+ - remove ':ignore_syntax_error', ':raise_missing_file' option
+ * 'Optimism#_walk' return nil instead of raising error
+ * 'Optimism#_store2' remove ':namespace' option
View
2 Gemfile
@@ -1,10 +1,8 @@
source :rubygems
gem "pd"
-gem "hike", "~>1.2.0"
group :development do
gem "rspec"
gem "watchr"
end
-
View
21 README.md
@@ -1,11 +1,13 @@
# Optimism, a configuration gem for Ruby [![Build Status](https://secure.travis-ci.org/GutenYe/optimism.png)](http://travis-ci.org/GutenYe/optimism)
-| Homepage: | https://github.com/GutenYe/optimism
-|----------------|--------------------------------------
-| Author: | Guten
-| License: | MIT-LICENSE
-| Documentation: | http://rubydoc.info/gems/optimism/frames
-| Issue Tracker: | https://github.com/GutenYe/optimism/issues
+| | |
+|----------------|---------------------------------------------|
+| Homepage: | https://github.com/GutenYe/optimism |
+| Author: | Guten |
+| License: | MIT-LICENSE |
+| Documentation: | http://rubydoc.info/gems/optimism/frames |
+| Issue Tracker: | https://github.com/GutenYe/optimism/issues |
+| Platforms: | Ruby 1.9.3, JRuby, Rubinius |
Features
--------
@@ -197,17 +199,12 @@ Resources
* [simpleconfig](https://github.com/lukeredpath/simpleconfig) make application-wide configuration settings easy to set and access in an object-oriented fashion
* [configuration](https://github.com/ahoward/configuration) pure ruby scoped configuration files
-Requirements
-------------
-
-* ruby 1.9.3
-
Copyright
---------
(MIT-LICENSE)
-Copyright (c) 2011 Guten
+Copyright (c) 2011-2012 Guten
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
View
574 lib/optimism.rb
@@ -1,15 +1,8 @@
-require 'hike'
+require "optimism/semantics"
+require "optimism/require"
-libdir = File.dirname(__FILE__)
-$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
-
-%w(
- semantics
- parser
- require
-).each { |n| require "optimism/#{n}" }
-
-# <#Optimism> is a node, it has _child, _parent and _root attribute.
+#
+# <#Optimism> is a node, it has _data, _parent and _root attribute.
#
# Rc = Optimism do
# a.b 1
@@ -26,96 +19,39 @@
# :d => 2>>>
#
# Rc.a #=> <#Optimism>
-# Rc.a._child #=> {:b => 1, :c => <#Optimism>}
+# Rc.a._data #=> {:b => 1, :c => <#Optimism>}
# Rc.a._parent #=> is Rc
# Rc.a._root #=> is Rc
#
# Rc._parent #=> nil
# Rc._root #=> is Rc
#
-#
# internal, string-key is converted into symbol-key
#
# Rc = Optimism.new
# Rc[:a] = 1
# Rc["a"] = 2
# p Rc[:a] #=> 2
#
-# if you want disable it. with :only_symbol_key => ture in constructor function.
-#
-#
+# if you want disable it. with :symbolize_key => ture in constructor function.
class Optimism
autoload :VERSION, "optimism/version"
+ autoload :Util, "optimism/util"
Error = Class.new Exception
MissingFile = Class.new Error
- EPath = Class.new Error
+ EPath = Class.new Error
EParse = Class.new Error
BUILTIN_METHODS = [:p, :sleep, :rand, :srand, :exit, :require, :at_exit, :autoload, :open, :send] # not :raise
class << self
public *BUILTIN_METHODS
public :undef_method
-
- include Require
-
- # get Hash data from any Hash or Optimism
- #
- # @param [Optimism, Hash] obj
- # @return [Hash]
- def get(obj)
- case obj
- when Hash
- obj
- when Optimism
- obj._child
- else
- raise ArgumentError, "wrong argument -- #{obj.inspect}"
- end
- end
-
- # convert Hash to Optimism
- #
- # @param [Optimism,Hash] data
- # @return [Optimism]
- def [](data)
- case data
- when Optimism
- data
- when Hash
- o = Optimism.new(:default => data.default)
- o._child = data
- o
- else
- raise ArgumentError, "wrong argument -- #{data.inspect}"
- end
- end
-
- # deep convert Hash to optimism
- #
- # @example
- # convert({a: {b: 1})
- # #=> Optimism[a: Optimism[b: 1]]
- #
- # @param [Hash,Optimism] hash
- # @return [Optimism]
- def convert(hash, options={})
- case hash
- when Optimism
- hash
- when Hash
- node = Optimism.new(:default => hash.default)
- hash.each { |k,v|
- node[k] = Hash===v ? convert(v, :name => k) : v
- }
- node
- else
- raise ArgumentError, "wrong argument -- #{hash.inspect}"
- end
- end
end
+ extend Require
+
undef_method *BUILTIN_METHODS
include Semantics
include RequireInstanceMethod
@@ -137,59 +73,129 @@ def _root
parent
end
- # child node, a hash data
- attr_accessor :_child
- alias _data _child
- alias _data= _child=
+ attr_accessor :_data
# initialize
#
# @example
#
# # with :default option
- # rc = Optimism.new(:default => 1)
+ # rc = Optimism.new(nil, default: 1)
# rc.i.donot.exists #=> 1
#
# # with :namespace option
# rc = Optimism.new("foo=1", :namespace => "a.b")
# rc.a.b.foo #=> 1
#
- # @overload initialize(content=nil, options={}, &blk)
- # @param [String] content
- # @overload initialize(options={}, &blk)
- # @param [Hash] options
- # @option options [Object] :default (nil) default value for Hash
- # @option options [String] :namespace
- # @option options [Boolean] :only_symbol_key (nil)
- def initialize(*args, &blk)
- raise ArgumentError, "wong argument -- #{args.inspect}" if args.size > 2
- case v=args.pop
+ # @param [String,Hash,Optimism] content
+ # @param [Hash] options
+ # @option options [Object] :default (nil) default value for Hash
+ # @option options [String] :namespace
+ # @option options [Boolean] :symbolize_key (true)
+ def initialize(content=nil, options={}, &blk)
+ @options = {symbolize_key: true}.merge(options)
+ @_parser = @options[:parser] || Optimism.parser
+ # first time value.
+ @_name = @options[:name] || :_
+ @_root = self
+ @_parent = nil
+
+ case content
+ # for first time.
when Hash
- @options = v
- content = args[0]
- else
- @options = {}
- content = v
+ @_data = _convert_hash(content)._data
+ # for first time.
+ when Optimsm
+ @_data = content._data
+ else
+ @_data = Hash.new(@options[:default])
+ _parse! content, &blk if content or blk
end
- @_name = @options[:name] || :_ # root name
- @_root = self # first time is self.
- @_parent = nil
- @_child = Hash.new(@options[:default])
-
_walk("-#{@options[:namespace]}", :build => true) if @options[:namespace]
+ end
+
+ # Returns true if same _data.
+ #
+ def ==(other)
+ case other
+ when Optimism
+ _data == other._data
+ else
+ false
+ end
+ end
- _eval(content, &blk) if content or blk
+ # deep merge new data IN PLACE
+ #
+ # @params [Hash,Optimism,String] other
+ # @return [self]
+ def _merge!(other)
+ other = case other
+ when String
+ Optimism.new(other)
+ else
+ Optimism.convert(other)
+ end
+
+ other._each { |k, v|
+ if Optimism === self[k] and Optimism === other[k]
+ self[k]._merge!(other[k])
+ else
+ self[k] = other[k]
+ end
+ }
- _root
+ self
+ end
+
+ alias << _merge!
+
+ # deep merge new data
+ #
+ # @params [Hash,Optimism] obj
+ # @return [Optimism] new <#Optimism>
+ def _merge(other)
+ self._dup._merge!(other)
+ end
+
+ alias + _merge
+
+ # duplicate
+ #
+ # @return [Optimism] new <#Optimism>
+ def _dup
+ o = Optimism.new(@options)
+ o._name = self._name
+ o._data = _data.dup
+ o._data.each {|k,v| v._parent = o if Optimism===v}
+
+ o
+ end
+
+ # replace with a new <#Optimism>
+ #
+ # @param [Optimism] obj
+ # @return [Optimism] self
+ def _replace(other)
+ # link
+ if self._parent then
+ self._parent[self._name] = _dup
+ end
+
+ self._parent = other._parent
+ self._name = other._name
+ self._data = other._data
+
+ self
end
# walk along the path.
#
# @param [String] path 'a.b' '-a.b'
# @param [Hash] options
# @option options [Boolean] (false) :build build the path if path doesn't exists.
- # @return [Optimism] the result node.
+ # @return [Optimism,nil] the result node.
def _walk(path, options={})
return self unless path
ret = path =~ /^-/ ? _walk_up(path[1..-1], options) : _walk_down(path, options)
@@ -204,23 +210,25 @@ def _walk!(path, options={})
path =~ /^-/ ? _walk_up!(path[1..-1], options) : _walk_down!(path, options)
end
+ def _has_key?(key)
+ _data.has_key?(_convert_key(key))
+ end
+
# support path
def _has_key2?(path)
- path, key = _split(path)
+ path, key = _split_path(path)
- begin
- node = _walk(path)
- rescue EPath
- false
+ node = _walk(path)
+
+ if node then
+ return node._has_key?(key)
else
- node._has_key?(key)
+ return false
end
end
def [](key)
- key = key.to_sym if String===key and !@options[:only_symbol_key]
-
- @_child[key]
+ @_data[_convert_key(key)]
end
# set data
@@ -232,91 +240,82 @@ def []=(key, value)
value._name = key.to_sym
end
- if String===key and !@options[:only_symbol_key]
- key = key.to_sym
- end
-
- @_child[key] = value
+ @_data[_convert_key(key)] = value
end
- # support path
+ # fetch with path support.
+ #
+ # @example
+ #
+ # o = Optimism do |c|
+ # c.a = 1
+ # c.b.c = 2
+ # end
+ #
+ # o._fetch2("not_exitts") -> nil
+ # o._fetch2("b.c") -> 2
+ # o._fetch2("c.d") -> nil. path doesn't exist.
+ # o._fetch2("a.b") -> nil. path is wrong
+ #
+ # @param [String] key
+ # @return [Object] value
def _fetch2(path, default=nil)
- path, key = _split(path)
+ path, key = _split_path(path)
- node = _walk(path, :build => true)
+ node = _walk(path)
- if node._has_key?(key)
- node[key]
+ if node & node._has_key?(k) then
+ return node[k]
else
- node[key] = default
+ return default
end
end
- # _store2 like _store, but support a path.
- # @see _walk
+ # store with path support.
#
# @exampe
#
# o = Optimism.new
# o._store2('a.b', 1) #=> 1, the value of a.b
#
# @param [Hash] o
- # @option o [String] :namespace => path
- # @option o [Boolean] (true) :build
# @return [Object] value
- def _store2(path, value, o={})
- o = {:build => true}.merge(o)
- path, key = _split(path)
+ def _store2(path, value)
+ path, key = _split_path(path)
- if path =~ /^-/
- tmp_node = _walk(path, :build => o[:build])
- tmp_node._walk(o[:namespace], :build => true)
- node = self
- else
- node = _walk(o[:namespace], :build => true)
- node = node._walk(path, :build => o[:build])
- end
+ node = _walk(path, :build => true)
node[key] = value
value
end
- # equal if same _child. not check _parent or _root.
- #
- def ==(other)
- case other
- when Optimism
- _child == other._child
- else
- false
- end
+ def _parse!(content=nil, &blk)
+ @_parser.call(self, content, &blk)
end
- # duplicate
- #
- # @return [Optimism] new <#Optimism>
- def _dup
- o = Optimism.new(@options)
- o._name = self._name
- o._child = _child.dup
- o._child.each {|k,v| v._parent = o if Optimism===v}
+ # pretty print
+ #
+ # <#Optimism
+ # :b => 1
+ # :c => 2
+ # :d => <#Optimism
+ # :c => 2>>
+ def inspect(indent=" ")
+ rst = ""
+ rst << "<#Optimism:#{_name}\n"
+ _data.each { |k,v|
+ rst << "#{indent}#{k.inspect} => "
+ rst << (Optimism === v ? "#{v.inspect(indent+" ")}\n" : "#{v.inspect}\n")
+ }
+ rst.rstrip! << ">"
- o
+ rst
end
- # replace with a new <#Optimism>
- #
- # @param [Optimism] obj
- # @return [Optimism] self
- def _replace(other)
- new_node = _dup
- self._parent[self._name] = new_node if self._parent # link
-
- self._parent = other._parent
- self._name = other._name
- self._child = other._child
+ alias to_s inspect
- self
+ def to_hash
+ _data
end
# everything goes here.
@@ -346,17 +345,17 @@ def method_missing(name, *args, &blk)
# .name=
elsif name =~ /(.*)=$/
- return @_child[$1.to_sym] = args[0]
+ return @_data[$1.to_sym] = args[0]
# ._name
elsif name =~ /^_(.*)/
name = $1.to_sym
- args.map!{|arg| Optimism===arg ? arg._child : arg}
- return @_child.__send__(name, *args, &blk)
+ args.map!{|arg| Optimism===arg ? arg._data : arg}
+ return @_data.__send__(name, *args, &blk)
# .name?
elsif name =~ /(.*)\?$/
- return !! @_child[$1.to_sym]
+ return !! @_data[$1.to_sym]
##
## a.c # return data if has :c
@@ -366,212 +365,56 @@ def method_missing(name, *args, &blk)
# p Rc.a.b.c #=> 1
# p Rc.a.b.c('bar')
#
- elsif @_child.has_key?(name)
- value = @_child[name]
- return (Proc===value && value.lambda?) ? value.call(*args) : value
+ elsif @_data.has_key?(name)
+ value = @_data[name]
+ return (Proc === value && value.lambda?) ? value.call(*args) : value
# p Rc.a.b.c #=> create new <#Optimism>
#
# a.b do |c|
# c.a = 2
# end
#
- # a.b <<-EOF
+ # a.b <<EOF
# a = 2
# EOF
- #
else
- next_o = Optimism.new(:default => @options[:default])
+ next_o = Optimism.new(nil, default: @options[:default])
self[name] = next_o # link the node
content = args[0]
- next_o.__send__ :_eval_contained_block, content, &blk if content or blk
+ next_o._parse! content, &blk
return next_o
end
end
- # pretty print
+private
+ # deep convert Hash to optimism.
+ # I'm rescursive.
#
- # <#Optimism
- # :b => 1
- # :c => 2
- # :d => <#Optimism
- # :c => 2>>
- def inspect(indent=" ")
- rst = ""
- rst << "<#Optimism:#{_name}\n"
- _child.each { |k,v|
- rst << "#{indent}#{k.inspect} => "
- rst << (Optimism === v ? "#{v.inspect(indent+" ")}\n" : "#{v.inspect}\n")
- }
- rst.rstrip! << ">"
-
- rst
- end
-
- alias to_s inspect
-
- def _to_hash
- _data
- end
-
- # deep merge new data IN PLACE
- #
- # @params [Hash,Optimism,String] other
- # @return [self]
- def _merge!(other)
- other = case other
- when String
- Optimism.new(other)
- else
- Optimism.convert(other)
- end
-
- other._each { |k, v|
- if Optimism === self[k] and Optimism === other[k]
- self[k]._merge!(other[k])
- else
- self[k] = other[k]
- end
- }
-
- self
- end
-
- alias << _merge!
-
- # deep merge new data
- #
- # @params [Hash,Optimism] obj
- # @return [Optimism] new <#Optimism>
- def _merge(other)
- self._dup._merge!(other)
- end
-
- alias + _merge
-
- # support path
+ # @overload _convert_hash(hash)
#
# @example
#
- # o = Optimism do |c|
- # c.a = 1
- # c.b.c = 2
- # end
+ # _convert_hash({a: {b: 1}) -> {:a => <#Optimism :b => 1>}
#
- # o._get("not_exitts") #=> nil
- # o._get("b.c") #=> 2
- # o._get("c.d") #=> nil. path doesn't exist.
- # o._get("a.b") #=> nil. path is wrong
- #
- # @param [String] key
- # @return [Object] value
- def _get(path)
- value = self
- if path =~ /\./
- path.split(".").each { |k|
- return nil unless Optimism === value # wrong path
- value = value[k.to_sym]
- return nil if value.nil? # path doesn't exist.
- }
- return value
- else
- return value[path.to_sym]
- end
- end
-
- def _has_key?(key)
- if String===key and !@options[:only_symbol_key]
- key = key.to_sym
- end
-
- _child.has_key?(key)
- end
+ # @param [Hash] hash
+ # @return [Optimism]
+ def _convert_hash(hash, options={})
+ node = Optimism.new(nil, {default: node.default}.merge(options))
-private
-
- # convert block to method.
- #
- # you can call a block with arguments
- #
- # @example USAGE
- # instance_eval(&blk)
- # blk2method(&blk).call *args
- #
- def _blk2method(&blk)
- self.class.class_eval {
- define_method(:__blk2method, &blk)
+ hash.each { |k,v|
+ node[k] = Hash === v ? _convert_hash(v, name: k) : v
}
- method(:__blk2method)
+ node
end
- # @option options [Boolean] :contained
- def _eval(content=nil, &blk)
- if content
- content = Parser::StringBlock2RubyBlock.new(content).evaluate
- content = Parser::Path2Lambda.new(content).evaluate
- _eval_string content
-
- _fix_lambda_values
- elsif blk
- _eval_block(&blk)
+ def _convert_key(key)
+ if @options[:symbolize_key] and String === key
+ key.to_sym
+ else
+ key
end
-
- end
-
- def _eval_contained_block(content=nil, &blk)
- content ? _eval_string(content) : _eval_block(&blk)
- end
-
- def _eval_block(&blk)
- meth = _blk2method(&blk)
- blk.arity == 0 ? meth.call : meth.call(self)
- end
-
- # parse the string content
- #
- # @param [String] content
- # @return nil
- def _eval_string(content)
- bind = binding
-
- vars = Parser::CollectLocalVariables.new(content).evaluate
-
- begin
- eval content, bind
- rescue SyntaxError => e
- raise EParse, "parse config file error.\n CONTENT: #{content}\n ERROR-MESSAGE: #{e.message}"
- exit
- end
-
- vars.each { |name|
- value = bind.eval(name)
- @_child[name.to_sym] = value
- }
-
- nil
- end
-
- # I'm rescurive
- #
- # for
- #
- # rc = Optimism <<-EOF
- # a = _.foo
- # EOF
- #
- # =>
- #
- # a = lambda{ _.foo }.tap{|s| s.instance_variable_set(:@_optimism, true)
- #
- def _fix_lambda_values
- @_child.each { |k,v|
- if Proc===v and v.lambda? and v.instance_variable_get(:@_optimism)
- @_child[k] = v.call
- elsif Optimism===v
- v.__send__ :_fix_lambda_values
- end
- }
end
# @see _walk
@@ -581,21 +424,21 @@ def _walk_down(path, options={})
nodes.each { |name|
name = name.to_sym
if node._has_key?(name)
- case node[name]
- when Optimism
+ if Optimism === node[name]
node = node[name]
else
- raise EPath, "wrong path: has a value along the path -- name(#{name}) value(#{node[name].inspect})"
+ return nil
end
else
if options[:build]
- new_node = Optimism.new(:default => @options[:default])
+ new_node = Optimism.new(nil, default: @options[:default])
node[name] = new_node # link the node.
node = new_node
else
- raise EPath, "path not exists. -- path: `#{path}'. cur-name: `#{name}'"
+ return nil
end
end
+
}
node
end
@@ -613,15 +456,15 @@ def _walk_up(path, options={})
if node._parent._name == name.to_sym
node = node._parent
else
- raise EPath, "wrong path: parent node doen't exists -- parent-name(#{node._parent._name}) current-name(#{name})"
+ return nil
end
else
if options[:build]
- new_node = Optimism.new(:default => @options[:default])
+ new_node = Optimism.new(nil, default: @options[:default])
new_node[name] = node # lnk the node.
node = new_node
else
- raise EPath, "path doesn't exist. -- path: `#{path}'. cur-name: `#{name}'"
+ return nil
end
end
}
@@ -640,10 +483,14 @@ def _walk_up!(path, options={})
_replace node
end
+ # split a path into path and key.
+ #
# "foo.bar.baz" => ["foo.bar", :baz]
# "foo" => [ "", :foo]
- def _split(path)
- paths = path.split('.')
+ #
+ # @return [Array] [path, key]
+ def _split_path(fullpath)
+ paths = fullpath.split('.')
if paths.size == 1
path = ""
key = paths[0].to_sym
@@ -657,8 +504,11 @@ def _split(path)
end
module Kernel
- # a handy method
+ # a short-cut to Optimism.new
def Optimism(*args, &blk)
- Optimism.new *args, &blk
+ Optimism.new(*args, &blk)
end
end
+
+require "optimism/parser"
+require "optimism/yaml"
View
130 lib/optimism/parser.rb
@@ -1,6 +1,6 @@
-class Optimism
- module Parser
- class Base
+class Optimism # ::Filter
+ class Parser
+ class Filter
attr_accessor :content
# input any thing
@@ -26,7 +26,7 @@ def evaluate
# database 'postgresql'
# end
#
- class StringBlock2RubyBlock < Base
+ class StringBlock2RubyBlock < Filter
INDENT=" "
# the string data.
@@ -47,7 +47,7 @@ def evaluate
case token
when :block_start
block_indent_counts << indent_counts
- statement = statement.sub(/\s*:/, " <<-OPTIMISM_EOF#{block_index}" )
+ statement = statement.sub(/\s*:/, " <<-OPTIMISM#{block_index}" )
block_index += 1
script << statement << "\n"
when :statement
@@ -61,7 +61,7 @@ def evaluate
indent_counts -= 1
if indent_counts == block_indent_counts[-1]
block_index -= 1
- script << INDENT*(indent_counts) + "OPTIMISM_EOF#{block_index}\n"
+ script << INDENT*(indent_counts) + "OPTIMISM#{block_index}\n"
block_indent_counts.pop
else
script << INDENT*(indent_counts)
@@ -130,22 +130,33 @@ def scan(content, &blk)
# foo = ___.name
# foo = true && _foo || _.bar
#
- class Path2Lambda < Base
+ class Path2Lambda < Filter
def initialize(content)
@content = content
end
def evaluate
content.split("\n").each.with_object("") { |line, memo|
line.split(";").each { |stmt|
- memo << stmt.gsub(/_+\.[a-z_][A-Za-z0-9_]*/){|m| " lambda { #{m} }.tap{|s| s.instance_variable_set(:@_optimism, true)} "}.rstrip
+ memo << stmt.gsub(/_+\.[a-z_][A-Za-z0-9_]*/){|m| " lambda { #{m} }.tap{|s| s.instance_variable_set(:@_is_optimism_path, true)} "}.rstrip
memo << "\n"
}
}
end
end
- class CollectLocalVariables < Base
+ #
+ # a <<-OPTIMISM0
+ # name = 2
+ # b <<-OPTIMISM1
+ # age = 1
+ # OPTIMISM1
+ # OPTIIMMS0
+ #
+ # ->
+ #
+ # [:name]
+ class CollectLocalVariables < Filter
LOCAL_VARIABLE_PAT=/(.*?)([a-zA-Z_.][a-zA-Z0-9_]*)\s*=[^~=]/
# @return [Array] local_variable_names
@@ -158,32 +169,121 @@ def evaluate
content.scan(LOCAL_VARIABLE_PAT).each.with_object([]) { |match, memo|
name = match[1]
next if name=~/^[A-Z.]/ # constant and method
- memo << name
+ memo << name.to_sym
}
end
private
# @example
# c = 1
- # a <<-OPTIMISM_EOF
+ # a <<-OPTIMISM
# b = 2
- # OPTIMISM_EOF
+ # OPTIMISM
# #=>
# c = 1
def remove_block_string(content)
content.gsub(/
(?<brace>
- (\A|\n)[^\n]+<<-OPTIMISM_EOF[0-9]+
+ (\A|\n)[^\n]+<<-OPTIMISM[0-9]+
(
- (?!<<-OPTIMISM_EOF|OPTIMISM_EOF).
+ (?!<<-OPTIMISM|OPTIMISM).
|
\g<brace>
)*
- OPTIMISM_EOF[0-9]+
+ OPTIMISM[0-9]+
)/mx, '')
end
end
end
end
+class Optimism # ::Parser
+ class Parser
+ def self.parse!(optimism, *args)
+ new(optimism).parse!(*args)
+ end
+
+ def initialize(optimism)
+ @optimism = optimism
+ end
+
+ def parse!(content=nil, &blk)
+ if content
+ eval_content(content)
+ elsif blk
+ eval_block(&blk)
+ end
+ end
+
+ private
+
+ #
+ # a.b do |c|
+ # c.pi = 3.14
+ # end
+ def eval_block(&blk)
+ @optimism.__send__ :instance_exec, @optimism, &blk
+ end
+
+ def eval_content(content)
+ content = Parser::StringBlock2RubyBlock.new(content).evaluate
+ content = Parser::Path2Lambda.new(content).evaluate
+
+ eval_string(content)
+
+ fix_lambda_path(@optimism)
+ end
+
+ # parse the string content
+ #
+ # @param [String] content
+ # @return nil
+ def eval_string(content)
+ vars = Parser::CollectLocalVariables.new(content).evaluate
+
+ begin
+ bind = @optimism.instance_eval do
+ bind = binding
+ eval content, bind
+ bind
+ end
+ rescue SyntaxError => e
+ raise EParse, "parse config file error.\n CONTENT: #{content}\n ERROR-MESSAGE: #{e.message}"
+ exit
+ end
+
+ vars.each { |name|
+ value = bind.eval(name.to_s)
+ @optimism._data[name] = value
+ }
+
+ nil
+ end
+
+ # I'm rescurive
+ #
+ # rc = Optimism <<EOF
+ # a = _.foo -> a = lambda{ _.foo }.tap{|s| s.instance_variable_set(:@_is_optimism_path, true)
+ # EOF
+ # ->
+ # a = 1
+ def fix_lambda_path(optimism)
+ data = optimism._data
+
+ data.each { |k,v|
+ if Proc === v and v.lambda? and v.instance_variable_get(:@_is_optimism_path)
+ data[k] = v.call
+ elsif Optimism === v
+ fix_lambda_path(v)
+ end
+ }
+ end
+ end
+end
+
+class Optimism
+ def self.parser
+ ->{|o,data,blk| Parser.parse!(o, data, &blk)}
+ end
+end
View
67 lib/optimism/require.rb
@@ -47,36 +47,30 @@ module Require
# @param [String] *paths
# @param [Hash] opts
# @option opts [String] :namespace wrap into a namespace.
- # @option opts [Boolean] :mixin (:replace) :replace :ignore
- # @option opts [Boolean] :ignore_syntax_error not raise SyntaxError
- # @option opts [Boolean] :raise_missing_file raise MissingFile
+ # @option opts [Boolean] :merge (:replace) :replace :ignore
# @return [Optimism]
def require_file(*paths)
- Hash === paths.last ? opts=paths.pop : opts={}
-
- opts[:mixin] ||= :replace
- error = opts[:ignore_syntax_error] ? SyntaxError : nil
+ paths, optimism_opts = Util.extract_options(paths, merge: :replace)
+ opts = [:namespace, :merge, :raise].each.with_object({}){|n, m|
+ m[n] = optimsm_opts.delete(n)
+ }
o = Optimism.new
paths.each { |name|
- path = find_file(name, opts)
+ path = find_file(name, {raise: opts[:raise]})
- unless path
- raise MissingFile if opts[:raise_missing_file]
- next
+ if File.extname(path) == "yml"
+ opts[:parser] = YAML.optimism_parser
end
- begin
- new = Optimism.new(File.read(path))
- rescue error
- end
+ o2 = Optimism.new(File.read(path), optimism_opts)
- case opts[:mixin]
+ case opts[:merge]
when :replace
- o << new
+ o << o2
when :ignore
- new << o
- o = new
+ o2 << o
+ o = o2
end
}
@@ -85,7 +79,19 @@ def require_file(*paths)
o
end
+ # same as require_file with raising error.
+ #
+ # raise MissingFile
+ #
+ # @see require_file
+ def require_file!(*paths)
+ paths, opts = Util.extract_options(paths)
+ opts[:raise] = true
+ require_file(*paths, opts)
+ end
+
alias require require_file
+ alias require! require_file!
# load configuration from environment variables.
# @see require_file
@@ -97,12 +103,12 @@ def require_file(*paths)
# ENV["OPTIMISM_B_C] = "b"
#
# # default is case_insensive
- # require_env("A") #=> Optimism[a: "1"]
- # require_env("A", :case_sensive => true) #=> Optimism[A: "1"]
+ # require_env("A") -> Optimism({a: 1})
+ # require_env("A", case_sensive: true) -> Optimism({A: 1})
#
# # with Regexp
- # require_env(/OPTIMISM_(.*)/) #=> Optimism[a: "a", b_c: "b"]
- # require_env(/OPTIMISM_(.*), :split => "_") #=> Optimism[a: "a", b: Optimism[c: "b"]]
+ # require_env(/OPTIMISM_(.*)/) -> Optimism({a: "a", b_c: "b"})
+ # require_env(/OPTIMISM_(.*), :split => "_") -> Optimism({a: "a", b: {c: "b"}})
#
# @overload require_env(*envs, opts={}, &blk)
# @param [String, Regexp] envs
@@ -134,7 +140,7 @@ def require_env(*args, &blk)
opts[:split] ||= /\Z/
- o = Optimism.new(:default => opts[:defualt])
+ o = Optimism.new(nil, default: opts[:defualt])
envs.each { |path, env|
path = opts[:case_sensive] ? path : path.downcase
path = path.split(opts[:split]).join('.')
@@ -174,6 +180,7 @@ def require_input(msg, path, o={}, &blk)
end
private
+ # option opts [Hash] :raise
def find_file(name, opts={})
path = nil
@@ -188,12 +195,16 @@ def find_file(name, opts={})
# name
else
- hike = Hike::Trail.new
- hike.extensions.push ".rb"
- hike.paths.replace $:
- path = hike.find(name)
+ path = $:.find.with_object("") { |p, file|
+ [".rb", ".yml", ""].each { |ext|
+ file.replace File.join(p, name+ext)
+ File.exists? file
+ }
+ }
end
+ raise MissingFile if path.nil? and opts[:raise] then
+
path
end
end
View
124 lib/optimism/util.rb
@@ -0,0 +1,124 @@
+require "rbconfig"
+
+class Optimism
+ # In order to reduce the dependencies, this Util class contains some util functions.
+ class Util
+ module Concern
+ def included(base)
+ base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
+ end
+ end
+
+ class << self
+ # Extracts options from a set of arguments.
+ #
+ # @example
+ #
+ # dirs, o = Util.extract_options(["foo", "bar", {a: 1}], b: 2)
+ # -> ["foo", "bar"], {a: 1, b: 2}
+ #
+ # (dir,) o = Util.extract_options(["foo", {a: 1}])
+ # -> "foo", {a: 1}
+ #
+ # @return [Array<Array,Hash>]
+ def extract_options(args, default={})
+ if args.last.instance_of?(Hash)
+ [args[0...-1], defalut.merge(args[-1])]
+ else
+ [args, default]
+ end
+ end
+
+ # Wraps its argument in an array unless it is already an array (or array-like).
+ #
+ # Specifically:
+ #
+ # * If the argument is +nil+ an empty list is returned.
+ # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
+ # * Otherwise, returns an array with the argument as its single element.
+ #
+ # Array.wrap(nil) # => []
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
+ # Array.wrap(0) # => [0]
+ #
+ # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
+ #
+ # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
+ # such a +nil+ right away.
+ # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
+ # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
+ #
+ # The last point is particularly worth comparing for some enumerables:
+ #
+ # Array(:foo => :bar) # => [[:foo, :bar]]
+ # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
+ #
+ # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
+ # Array.wrap("foo\nbar") # => ["foo\nbar"]
+ #
+ # There's also a related idiom that uses the splat operator:
+ #
+ # [*object]
+ #
+ # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
+ #
+ # Thus, in this case the behavior is different for +nil+, and the differences with
+ # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
+ def array_wrap(object)
+ if object.nil?
+ []
+ elsif object.respond_to?(:to_ary)
+ object.to_ary || [object]
+ else
+ [object]
+ end
+ end
+
+ # different to File.join.
+ #
+ # @example
+ #
+ # path_join(".", "foo") -> "foo" not "./foo"
+ #
+ def path_join(dir, *names)
+ dir == "." ? File.join(*names) : File.join(dir, *names)
+ end
+
+ def linux?
+ RbConfig::CONFIG["host_os"] =~ /linux|cygwin/
+ end
+
+ def mac?
+ RbConfig::CONFIG["host_os"] =~ /mac|darwin/
+ end
+
+ def bsd?
+ RbConfig::CONFIG["host_os"] =~ /bsd/
+ end
+
+ def windows?
+ RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
+ end
+
+ def solaris?
+ RbConfig::CONFIG["host_os"] =~ /solaris|sunos/
+ end
+
+ # TODO: who knows what symbian returns?
+ def symbian?
+ RbConfig::CONFIG["host_os"] =~ /symbian/
+ end
+
+ def posix?
+ linux? or mac? or bsd? or solaris? or begin
+ fork do end
+ true
+ rescue NotImplementedError, NoMethodError
+ false
+ end
+ end
+ end
+ end
+end
View
2 lib/optimism/version.rb
@@ -1,3 +1,3 @@
class Optimism
- VERSION = "3.2.1"
+ VERSION = "3.3.0"
end
View
5 lib/optimism/yaml.rb
@@ -0,0 +1,5 @@
+module YAML
+ def self.optimiam_parser
+ ->{|o,data| o << self.load(data)}
+ end
+end
View
2 optimism.gemspec
@@ -14,6 +14,4 @@ a configuration library for Ruby
s.rubyforge_project = "xx"
s.files = `git ls-files`.split("\n")
-
- s.add_dependency "hike", "~>1.2.0"
end
View
10 spec/optimism/hash_method_fix_spec.rb
@@ -7,10 +7,10 @@
o = Optimism.new
o.b._merge! a: 1
- o.should == Optimism[b: Optimism[a: 1]]
+ o.should == Optimism({b: {a: 1}})
- o.b._merge! Optimism[a: 2]
- o.should == Optimism[b: Optimism[a: 2]]
+ o.b._merge! Optimism({a: 2})
+ o.should == Optimism({b: {a: 2}})
end
#
@@ -42,7 +42,7 @@
end
o._merge! o2
- o.should == Optimism[a: Optimism[b: 2, c: "foo", d: "bar"], b: Optimism[c: "x"]]
+ o.should == Optimism({a: {b: 2, c: "foo", d: "bar"}, b: {c: "x"}})
end
end
@@ -51,7 +51,7 @@
o = Optimism.new
new = o._merge a: 1
o.should == o
- new.should == Optimism[a: 1]
+ new.should == Optimism({a: 1})
end
end
View
24 spec/optimism/require_spec.rb
@@ -37,17 +37,17 @@ module Optimism::Require
describe ".require_file" do
it "works with :namespace" do
o = Optimism.require("data/rc", :namespace => "a.b")
- o.should == Optimism[a: Optimism[b: Optimism[a: 1]]]
+ o.should == Optimism({a: {b: {a: 1}}})
end
it "works on :mixin with :replace" do
o = Optimism.require("data/mixin_a", "data/mixin_b", :mixin => :replace)
- o.should == Optimism[a: Optimism[b: 2, c: "foo", d: "bar"]]
+ o.should == Optimism({a: {b: 2, c: "foo", d: "bar"}})
end
it "works on :mixin with :ignore" do
o = Optimism.require("data/mixin_a", "data/mixin_b", :mixin => :ignore)
- o.should == Optimism[a: Optimism[b: 1, c: "foo", d: "bar"]]
+ o.should == Optimism({a: {b: 1, c: "foo", d: "bar"}})
end
it "raise InvalidSyntax" do
@@ -73,29 +73,29 @@ module Optimism::Require
it "load an environment variable" do
o = Optimism.require_env("A")
- o.should == Optimism[a: "1"]
+ o.should == Optimism({a: "1"})
end
it "with :case_sensive option" do
o = Optimism.require_env("A", :case_sensive => true)
- o.should == Optimism[A: "1"]
+ o.should == Optimism({A: "1"})
end
it "support block, convert value to integer." do
o = Optimism.require_env("A") { |a|
a.to_i
}
- o.should == Optimism[a: 1]
+ o.should == Optimism({a: 1})
end
it "load multiplate environment variables at once" do
o = Optimism.require_env("A", "B")
- o.should == Optimism[a: "1", b: "2"]
+ o.should == Optimism({a: "1", b: "2"})
end
it "load by pattern" do
o = Optimism.require_env(/OPTIMISM_(.*)/)
- o.should == Optimism[a: "1", b_c: "2"]
+ o.should == Optimism({a: "1", b_c: "2"})
end
it "load by pattern, but env not exists" do
@@ -105,7 +105,7 @@ module Optimism::Require
it "load by pattern with :split" do
o = Optimism.require_env(/OPTIMISM_(.*)/, :split => "_")
- o.should == Optimism[a: "1", b: Optimism[c: "2"]]
+ o.should == Optimism({a: "1", b: {c: "2"}})
end
end
@@ -116,23 +116,23 @@ module Optimism::Require
def gets() "guten\n" end
end
o = Optimism.require_input("what's your name?", "my.name")
- o.should == Optimism[my: Optimism[name: "guten"]]
+ o.should == Optimism({my: {name: "guten"}})
end
it "with :default option" do
module Optimism::Require
def gets() "\n" end
end
o = Optimism.require_input("what's your name?", "my.name", default: "foo")
- o.should == Optimism[my: Optimism[name: "foo"]]
+ o.should == Optimism({my: {name: "foo"}})
end
it "call with block" do
module Optimism::Require
def gets() "1\n" end
end
o = Optimism.require_input("how old are you?", "age") { |age| age.to_i }
- o.should == Optimism[age: 1]
+ o.should == Optimism({age: 1})
end
end
View
143 spec/optimism_spec.rb
@@ -1,81 +1,52 @@
require "spec_helper"
$:.unshift $spec_dir
-=begin
-
-quick create a <#Optimism>
- * Optimism.convert({a: {b: 2}})
- * Optimism[a: Optimism[b: 1]] # each node has no _parent and _root.
-
-equal
- o1 == o2 # check Class, and _child. not check _parent or _root
-=end
-
class Optimism
public :_fix_lambda_values, :_walk, :_split
end
+def build(hash)
+ o = Optimsm.new
+ o._data = hash
+ o
+end
+
describe Optimism do
# first
describe "#==" do
it "" do
- a = Optimism.new
- a._child = {a: 1}
-
- b = Optimism.new
- b._child = {a: 1}
+ a = build(a: 1)
+ b = build(a: 1)
a.should == b
end
end
- describe ".[]" do
- it "converts Hash to Optimism" do
- o = Optimism[a: Optimism[b: 1]]
-
- a = Optimism.new
- a._child = {b: 1}
- right = Optimism.new
- right._child = {a: a}
- o.should == right
- end
-
- it "converts Optimism to Optimism" do
- node = Optimism[a: 1]
-
- Optimism[node].should == node
- end
- end
- describe ".convert" do
+ describe ".[]" do
it "simple hash data" do
- Optimism.convert({a: 1}).should == Optimism[a: 1]
+ Optimism({a: 1}).should == build(a: 1)
end
it "complex hash data" do
- #Optimism.convert({a: 1, b: {c: 1}}).should == Optimism[a: 1, b: Optimism[c: 1]]
- o = Optimism.convert({a: 1, b: {c: 1}})
+ Optimism({a: 1, b: {c: 1}}).should == build(a: 1, b: build(c: 1))
end
it "simple optimism data " do
- o = Optimism[a: 1]
- Optimism.convert(o).should == o
+ o = Optimism(a: 1)
+ Optimism(o).should == o
end
it "complex optimism data" do
- data = {
- a: 1,
- b: Optimism[c: 2],
- c: {
- e: Optimism[d: 3]
- }
- }
- right = Optimism[a: 1, b: Optimism[c: 2], c: Optimism[e: Optimism[d: 3]]]
- Optimism.convert(data).should == right
+ data = { a: 1, b: build(c: 2), d: {e: 3}
+ right = build(a: 1, b: build(c: 2), d: build(e: 3)))
+
+ Optimism(data).should == right
end
end
+
describe "#inspect" do
it "works" do
- o = Optimism.convert({a: 1, c: {d: {e: 3}}})
+ o = Optimism({a: 1, c: {d: {e: 3}}})
expect = <<-EOF.rstrip
<#Optimism:_
:a => 1
@@ -90,7 +61,7 @@ class Optimism
describe "#_root" do
it "works" do
- o = Optimism.convert({a: {b: {c: 1}}})
+ o = Optimism({a: {b: {c: 1}}})
o.a.b._root.should == o
end
end
@@ -101,8 +72,8 @@ class Optimism
Optimism.get(data).should == {a: 1}
end
it "gets data from Optimism" do
- o = Optimism.new
- o._child = {a: 1}
+ o = lptimism.new
+ o._data = {a: 1}
Optimism.get(o).should == {a: 1}
end
end
@@ -114,7 +85,7 @@ class Optimism
my:
a = lambda { 2 }.tap{|s| s.instance_variable_set(:@_optimism, true)}
EOF
- rc.should == Optimism[a: 1, my: Optimism[a: 2]]
+ rc.should == Optimism({a: 1, my: {a: 2}})
end
end
@@ -126,7 +97,7 @@ class Optimism
c.d = _.a
end
end
- rc.should == Optimism[b: Optimism[c: Optimism[d: 1]], a: 1]
+ rc.should == Optimism({b: {c: {d: 1}}, a: 1})
end
end
@@ -135,7 +106,7 @@ class Optimism
rc = Optimism <<-EOF
a = 1
EOF
- rc.should == Optimism[a: 1]
+ rc.should == Optimism({a: 1})
end
it "with complex example" do
@@ -144,14 +115,14 @@ class Optimism
b.c:
d = _.a
EOF
- rc.should == Optimism[b: Optimism[c: Optimism[d: 1]], a: 1]
+ rc.should == Optimism({b: {c: {d: 1}}, a: 1})
end
end
context "access" do
before :all do
- @rc = Optimism[a: 1]
- @rc._child = {a: 1}
+ @rc = Optimism({a: 1})
+ @rc._data = {a: 1}
end
it "#name" do
@@ -211,7 +182,7 @@ class Optimism
end
it "if true" do
- o = Optimism.new(only_symbol_key: true)
+ o = Optimism.new(nil, only_symbol_key: true)
o[:a] = 1
o[:a].should == 1
@@ -229,14 +200,14 @@ class Optimism
rc = Optimism do |c|
c.a.b.c = 1
end
- rc.should == Optimism[a: Optimism[b: Optimism[c:1]]]
+ rc.should == Optimism({a: {b: {c:1}}})
end
it "supports basic namespace with string-syntax" do
rc = Optimism <<-EOF
a.b.c = 1
EOF
- rc.should == Optimism[a: Optimism[b: Optimism[c: 1]]]
+ rc.should == Optimism({a: {b: {c: 1}}})
end
it "supports basic2 namespace with ruby-syntax" do
@@ -245,15 +216,15 @@ class Optimism
c.c = 1
end
end
- rc.should == Optimism[a: Optimism[b: Optimism[c:1]]]
+ rc.should == Optimism({a: {b: {c:1}}})
end
it "supports basic2 namespace with string-syntax" do
rc = Optimism <<-EOF
a.b:
c = 1
EOF
- rc.should == Optimism[a: Optimism[b: Optimism[c: 1]]]
+ rc.should == Optimism({a: {b: {c: 1}}})
end
it "supports complex namespace with ruby-syntax" do
@@ -269,7 +240,7 @@ class Optimism
end
end
- rc.should == Optimism[age: 1, my: Optimism[age: 2, friend: Optimism[age: 3]]]
+ rc.should == Optimism({age: 1, my: {age: 2, friend: {age: 3}}})
end
it "supports complex namespace with string-syntax" do
@@ -283,7 +254,7 @@ class Optimism
age = 3
EOF
- rc.should == Optimism[age: 1, my: Optimism[age: 2, friend: Optimism[age: 3]]]
+ rc.should == Optimism({age: 1, my: {age: 2, friend: {age: 3}}})
end
end
@@ -419,7 +390,7 @@ class Optimism
context "hash compatibility" do
it "works" do
- rc = Optimism[a: 1]
+ rc = Optimism(a: 1)
rc._keys.should == [:a]
end
@@ -431,19 +402,19 @@ class Optimism
end
describe "#_to_hash" do
- o = Optimism.convert({a: {b: {c: 1}}})
- o._to_hash.should == {a: Optimism.convert({b: {c: 1}})}
+ o = Optimism({a: {b: {c: 1}}})
+ o._to_hash.should == {a: Optimism({b: {c: 1}})}
end
describe "#_walk" do
it "down along the path" do
- o = Optimism.convert({a: {b: {c: 1}}})
+ o = Optimism({a: {b: {c: 1}}})
node = o._walk('a.b')
- node.should == Optimism[c: 1]
+ node.should == Optimism({c: 1})
end
it "up along the path" do
- o = Optimism.convert({a: {b: {c: 1}}})
+ o = Optimism({a: {b: {c: 1}}})
node = o._walk('a.b')
node2 = node._walk('-_.a')
node2.should == o
@@ -453,28 +424,28 @@ class Optimism
o = Optimism.new
lambda {node = o._walk('a.b')}.should raise_error(Optimism::EPath)
node = o._walk('a.b', :build => true)
- o.should == Optimism[a: Optimism[b: Optimism.new]]
+ o.should == Optimism(a: {b: Optimism.new})
end
it "up along the path with :build" do
o = Optimism.new
lambda {node = o._walk('-a.b')}.should raise_error(Optimism::EPath)
node = o._walk('-a.b', :build => true)
- node.should == Optimism[a: Optimism[b: Optimism.new]]
+ node.should == Optimism(a: {b: Optimism.new})
end
end
describe "#_walk!" do
it "down along the path" do
o = Optimism.new
o._walk!('a.b', :build => true)
- o._root.should == Optimism[a: Optimism[b: Optimism.new]]
+ o._root.should == Optimism(a: {b: Optimism.new})
end
it "up along the path" do
o = Optimism.new
o._walk!('-a.b', :build => true)
- o.should == Optimism[a: Optimism[b: Optimism.new]]
+ o.should == Optimism(a: {b: Optimism.new})
end
end
@@ -487,7 +458,7 @@ class Optimism
describe "#_has_key2?" do
it "works" do
- a = Optimism.convert({foo: {bar: 1}})
+ a = Optimism({foo: {bar: 1}})
a._has_key2?("foo").should be_true
a._has_key2?("foo.bar").should be_true
@@ -498,7 +469,7 @@ class Optimism
describe "#_fetch2" do
before :each do
- @o = Optimism.convert({a: {b: {c: 1}}})
+ @o = Optimism({a: {b: {c: 1}}})
end
it "works" do
@@ -518,7 +489,7 @@ class Optimism
it "works with default :build is true" do
@o._store2 'a.b', 1
- @o.should == Optimism[a: Optimism[b: 1]]
+ @o.should == Optimism({a: {b: 1}})
end
it "works with :build => false" do
@@ -528,17 +499,17 @@ class Optimism
describe "#_repalce" do
it "works" do
- a = Optimism.convert({foo: {bar: 1}})
+ a = Optimism({foo: {bar: 1}})
b = Optimism.new
b._replace a.foo
- b.should == Optimism[bar: 1]
+ b.should == Optimism(bar: 1)
b._root.should == a
end
end
describe "marshal" do
it "works" do
- rc = Optimism.convert({a: 1, b: {c: 2}})
+ rc = Optimism({a: 1, b: {c: 2}})
content = Marshal.dump(rc)
ret = Marshal.load(content)
ret.should == rc
@@ -550,10 +521,10 @@ class Optimism
o = Optimism.new
o.b._merge! a: 1
- o.should == Optimism[b: Optimism[a: 1]]
+ o.should == Optimism({b: {a: 1}})
- o.b._merge! Optimism[a: 2]
- o.should == Optimism[b: Optimism[a: 2]]
+ o.b._merge! Optimism({a: 2})
+ o.should == Optimism({b: {a: 2}})
end
#
@@ -585,7 +556,7 @@ class Optimism
end
o._merge! o2
- o.should == Optimism[a: Optimism[b: 2, c: "foo", d: "bar"], b: Optimism[c: "x"]]
+ o.should == Optimism({a: {b: 2, c: "foo", d: "bar"}, b: {c: "x"}})
end
it "(string)" do
@@ -594,7 +565,7 @@ class Optimism
a = 1
EOF
- o.should == Optimism.convert({a: 1})
+ o.should == Optimism({a: 1})
end
end
@@ -603,7 +574,7 @@ class Optimism
o = Optimism.new
new = o._merge a: 1
o.should == o
- new.should == Optimism[a: 1]
+ new.should == Optimism(a: 1)
end
end
View
6 spec/spec_helper.rb
@@ -44,3 +44,9 @@ def xit(*args, &blk)
end
end
end
+
+class Optimism
+ class << self
+ public :[]
+ end
+end

0 comments on commit b788d3c

Please sign in to comment.