lib/openwfe/utils.rb in ruote-0.9.18 vs lib/openwfe/utils.rb in ruote-0.9.19
- old
+ new
@@ -1,554 +1,527 @@
#
#--
# Copyright (c) 2005-2008, John Mettraux, OpenWFE.org
# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
+#
+# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
-#
+#
# . Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-#
-# . Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
+# list of conditions and the following disclaimer.
+#
+# . Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
-#
+#
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#++
#
#
# "hecho en Costa Rica" and "made in Japan"
#
# john.mettraux@openwfe.org
#
-require 'rexml/document'
+require 'openwfe/rexml'
require 'tmpdir'
require 'open-uri'
module OpenWFE
- #
- # see
- # http://wiki.rubygarden.org/Ruby/page/show/Make_A_Deep_Copy_Of_An_Object
- #
- # It's not perfect (that's why fulldup() uses it only in certain cases).
- #
- # For example :
- #
- # TypeError: singleton can't be dumped
- # ./lib/openwfe/utils.rb:74:in `dump'
- # ./lib/openwfe/utils.rb:74:in `deep_clone'
- #
- def OpenWFE.deep_clone (object)
+ #--
+ # see
+ # http://wiki.rubygarden.org/Ruby/page/show/Make_A_Deep_Copy_Of_An_Object
+ #
+ # It's not perfect (that's why fulldup() uses it only in certain cases).
+ #
+ # For example :
+ #
+ # TypeError: singleton can't be dumped
+ # ./lib/openwfe/utils.rb:74:in `dump'
+ # ./lib/openwfe/utils.rb:74:in `deep_clone'
+ #
+ #def OpenWFE.deep_clone (object)
+ # Marshal.load(Marshal.dump(object))
+ #end
+ #++
- Marshal::load(Marshal.dump(object))
- end
+ #--
+ # classes that shouldn't get duplicated.
+ #
+ #IMMUTABLES = [ Symbol, Fixnum, TrueClass, FalseClass, Float ]
+ #++
- #
- # an automatic dup implementation attempt
- #
- def OpenWFE.fulldup (object)
+ #
+ # an automatic dup implementation attempt
+ #
+ def OpenWFE.fulldup (object)
- return nil if object == nil
-
- return object.fulldup if object.respond_to?("fulldup")
- # trusting client objects providing a fulldup() implementation
- # Tomaso Tosolini 2007.12.11
+ return object.fulldup if object.respond_to?("fulldup")
+ # trusting client objects providing a fulldup() implementation
+ # Tomaso Tosolini 2007.12.11
- return object if object.kind_of?(Float)
- return object if object.kind_of?(Fixnum)
- return object if object.kind_of?(TrueClass)
- return object if object.kind_of?(FalseClass)
- return object if object.kind_of?(Symbol)
+ begin
+ return Marshal.load(Marshal.dump(object))
+ # as soon as possible try to use that Marshal technique
+ # it's quite fast
+ rescue TypeError => te
+ end
- return object.dup if object.kind_of?(String)
+ if object.kind_of?(REXML::Element)
+ d = REXML::Document.new object.to_s
+ return d if object.kind_of?(REXML::Document)
+ return d.root
+ end
+ # avoiding "TypeError: singleton can't be dumped"
- #return deep_clone(object) if object.kind_of?(REXML::Document)
-
- #return REXML::Document.new(object.to_s) \
- # if object.kind_of? REXML::Document
+ o = object.class.new
- if object.kind_of?(REXML::Element)
- d = REXML::Document.new object.to_s
- return d if object.kind_of?(REXML::Document)
- return d.root
- end
+ #
+ # some kind of collection ?
+ if object.kind_of?(Array)
+ object.each { |i| o << fulldup(i) }
+ elsif object.kind_of?(Hash)
+ object.each { |k, v| o[fulldup(k)] = fulldup(v) }
+ end
+ #
+ # duplicate the attributes of the object
+ object.instance_variables.each do |v|
+ #puts "v is #{v}"
+ value = object.instance_variable_get(v)
+ #puts "value is '#{value}'"
+ value = fulldup(value)
+ begin
+ o.instance_variable_set(v, value)
+ rescue
+ # ignore, must be readonly
+ end
+ end
- return deep_clone(object) if object.is_a?(Date)
+ o
+ end
- return Time.at(object) if object.is_a?(Time)
- # patch by Maarten Oelering
+ def OpenWFE.to_underscore (string)
- return Rational(object.denominator, object.numerator) \
- if object.kind_of?(Rational)
+ string.gsub("-", "_")
+ end
- o = nil
+ def OpenWFE.to_dash (string)
- begin
- o = object.class.new
- rescue ArgumentError => ae
- return deep_clone(object)
- end
+ string.gsub("_", "-")
+ end
- #
- # some kind of collection ?
+ def OpenWFE.symbol_to_name (symbol)
- if object.kind_of?(Array)
- object.each do |i|
- o << fulldup(i)
- end
- elsif object.kind_of?(Hash)
- object.each do |k, v|
- o[fulldup(k)] = fulldup(v)
- end
- end
+ to_dash(symbol.to_s)
+ end
- #
- # duplicate the attributes of the object
+ def OpenWFE.name_to_symbol (name)
- object.instance_variables.each do |v|
+ return name if name.is_a?(Symbol)
+ to_underscore(name).intern
+ end
- #puts "v is #{v}"
+ #
+ # Turns all the spaces in string into underscores.
+ # Returns the new String.
+ #
+ def OpenWFE.stu (s)
- value = object.instance_variable_get(v)
+ s.gsub("\s", "_")
+ end
- #puts "value is '#{value}'"
+ #
+ # Returns an URI if the string is one, else returns nil.
+ # No exception is thrown by this method.
+ #
+ def OpenWFE.parse_uri (string)
- value = fulldup(value)
+ return nil if string.split("\n").size > 1
- begin
- o.instance_variable_set(v, value)
- rescue
- # ignore, must be readonly
- end
- end
-
- o
+ begin
+ return URI::parse(string)
+ rescue Exception => e
end
- def OpenWFE.to_underscore (string)
+ nil
+ end
- string.gsub("-", "_")
- end
+ #
+ # Returns a URI instance if the given ref is a http, https, file or ftp
+ # URI. Returns nil else.
+ # The sister method parse_uri() is OK with things like mailto:, gopher:, ...
+ #
+ def OpenWFE.parse_known_uri (ref)
- def OpenWFE.to_dash (string)
+ uri = OpenWFE::parse_uri(ref.to_s)
- string.gsub("_", "-")
- end
+ return nil unless uri
- def OpenWFE.symbol_to_name (symbol)
+ return uri if uri.scheme == "file"
+ return uri if uri.scheme == "http"
+ return uri if uri.scheme == "https"
+ return uri if uri.scheme == "ftp"
+ # what else ...
- to_dash(symbol.to_s)
- end
+ nil
+ end
- def OpenWFE.name_to_symbol (name)
-
- return name if name.is_a?(Symbol)
- to_underscore(name).intern
- end
-
+ #
+ # Returns true if the given string starts with the 'start' string.
+ #
+ def OpenWFE.starts_with (string, start)
#
- # Turns all the spaces in string into underscores.
- # Returns the new String.
+ # my favourite way of doing that would be by adding this
+ # method to the String class, but that could be intrusive
+ # (as OpenWFE is meant at first as an embeddable workflow engine).
#
- def OpenWFE.stu (s)
+ return false unless string
+ return false if string.length < start.length
+ string[0, start.length] == start
+ end
- s.gsub("\s", "_")
- end
+ #
+ # Returns true if the given string ends with the '_end' string.
+ #
+ def OpenWFE.ends_with (string, _end)
+ return false unless string
+ return false if string.length < _end.length
+ string[-_end.length..-1] == _end
+ end
- #
- # Returns an URI if the string is one, else returns nil.
- # No exception is thrown by this method.
- #
- def OpenWFE.parse_uri (string)
+ #
+ # Attempts at displaying a nice stack trace
+ #
+ def OpenWFE.exception_to_s (exception)
+ s = "exception : "
+ s << "#{exception}\n"
+ s << exception.backtrace.join("\n")
+ s
+ end
- return nil if string.split("\n").size > 1
-
- begin
- return URI::parse(string)
- rescue Exception => e
- end
-
- nil
+ #
+ # Pretty printing a caller() array
+ #
+ def OpenWFE.caller_to_s (start_index, max_lines=nil)
+ s = ""
+ caller(start_index + 1).each_with_index do |line, index|
+ break if max_lines and index >= max_lines
+ s << " #{line}\n"
end
+ s
+ end
- #
- # Returns a URI instance if the given ref is a http, https, file or ftp
- # URI. Returns nil else.
- # The sister method parse_uri() is OK with things like mailto:, gopher:, ...
- #
- def OpenWFE.parse_known_uri (ref)
+ #
+ # Sets the name of the current thread (the attribute :name if it is
+ # a ruby thread, the java thread name if we're in JRuby)
+ #
+ def OpenWFE.set_current_thread_name (name)
- uri = OpenWFE::parse_uri(ref.to_s)
+ if defined?(JRUBY_VERSION)
+ require 'java'
+ java.lang.Thread.current_thread.name = "#{name} (Ruby Thread)"
+ end
- return nil unless uri
+ Thread.current[:name] = name
+ end
- return uri if uri.scheme == "file"
- return uri if uri.scheme == "http"
- return uri if uri.scheme == "https"
- return uri if uri.scheme == "ftp"
- # what else ...
+ #
+ # Some code for writing thinks like :
+ #
+ # if async
+ # OpenWFE::call_in_thread "launch()", self do
+ # raw_expression.apply(wi)
+ # end
+ # else
+ # raw_expression.apply(wi)
+ # end
+ #
+ # Returns the new thread instance.
+ #
+ def OpenWFE.call_in_thread (caller_name, caller_object=nil, &block)
- nil
- end
+ return unless block
- #
- # Returns true if the given string starts with the 'start' string.
- #
- def OpenWFE.starts_with (string, start)
- #
- # my favourite way of doing that would be by adding this
- # method to the String class, but that could be intrusive
- # (as OpenWFE is meant at first as an embeddable workflow engine).
- #
- return false unless string
- return false if string.length < start.length
- string[0, start.length] == start
- end
+ Thread.new do
- #
- # Returns true if the given string ends with the '_end' string.
- #
- def OpenWFE.ends_with (string, _end)
- return false unless string
- return false if string.length < _end.length
- string[-_end.length..-1] == _end
- end
+ #Thread.current[:name] = caller_name
+ set_current_thread_name caller_name
- #
- # Attempts at displaying a nice stack trace
- #
- def OpenWFE.exception_to_s (exception)
- s = "exception : "
- s << "#{exception}\n"
- s << exception.backtrace.join("\n")
- s
- end
+ begin
+ #$SAFE = safe_level
+ #
+ # (note)
+ # doesn't work : the block inherits the safety level
+ # of its surroundings, it's a closure, ne ?
- #
- # Pretty printing a caller() array
- #
- def OpenWFE.caller_to_s (start_index, max_lines=nil)
- s = ""
- caller(start_index + 1).each_with_index do |line, index|
- break if max_lines and index >= max_lines
- s << " #{line}\n"
+ block.call
+
+ rescue Exception => e
+ msg = "#{caller_name} caught an exception\n" + exception_to_s(e)
+ if caller_object and caller_object.respond_to? :lwarn
+ caller_object.lwarn { msg }
+ else
+ puts msg
end
- s
+ end
end
+ # returns the thread
+ end
- #
- # Sets the name of the current thread (the attribute :name if it is
- # a ruby thread, the java thread name if we're in JRuby)
- #
- def OpenWFE.set_current_thread_name (name)
+ #
+ # A small Timer class for debug purposes.
+ #
+ # t = Time.new
+ #
+ # # ... do something
+ #
+ # puts "that something took #{t.duration} ms"
+ #
+ class Timer
- if defined?(JRUBY_VERSION)
- require 'java'
- java.lang.Thread.current_thread.name = "#{name} (Ruby Thread)"
- end
+ attr_reader :start
- Thread.current[:name] = name
+ def initialize
+ @start = Time.now.to_f
end
#
- # Some code for writing thinks like :
+ # Returns the number of milliseconds since this Timer was
+ # instantiated.
#
- # if async
- # OpenWFE::call_in_thread "launch()", self do
- # raw_expression.apply(wi)
- # end
- # else
- # raw_expression.apply(wi)
- # end
- #
- # Returns the new thread instance.
- #
- def OpenWFE.call_in_thread (caller_name, caller_object=nil, &block)
+ def duration
+ (Time.now.to_f - @start) * 1000
+ end
+ end
- return unless block
- Thread.new do
+ #
+ # (2008.03.12 Deprecated, kept here for a while
+ # for backward compatibility)
+ #
+ # A simple Hash that accepts String or Symbol as lookup keys []
+ #
+ class SymbolHash < Hash
+ def [] (key)
+ super(key.to_s)
+ end
+ end
- #Thread.current[:name] = caller_name
- set_current_thread_name caller_name
+ #
+ # Returns a version of s that is usable as or within a filename
+ # (removes for examples things like '/' or '\'...)
+ #
+ def OpenWFE.ensure_for_filename (s)
- begin
- #$SAFE = safe_level
- #
- # (note)
- # doesn't work : the block inherits the safety level
- # of its surroundings, it's a closure, ne ?
+ s = s.gsub(" ", "_")
+ s = s.gsub("/", "_")
+ s = s.gsub(":", "_")
+ s = s.gsub(";", "_")
+ s = s.gsub("\*", "_")
+ s = s.gsub("\\", "_")
+ s = s.gsub("\+", "_")
+ s = s.gsub("\?", "_")
- block.call
+ s
+ end
- rescue Exception => e
- msg = "#{caller_name} caught an exception\n" + exception_to_s(e)
- if caller_object and caller_object.respond_to? :lwarn
- caller_object.lwarn { msg }
- else
- puts msg
- end
- end
- end
- # returns the thread
- end
+ #
+ # "my//path" -> "my/path"
+ #
+ def OpenWFE.clean_path (s)
+ s.gsub(/\/+/, "/")
+ end
- #
- # A small Timer class for debug purposes.
- #
- # t = Time.new
- #
- # # ... do something
- #
- # puts "that something took #{t.duration} ms"
- #
- class Timer
+ #
+ # This method is used within the InFlowWorkItem and the CsvTable classes.
+ #
+ def OpenWFE.lookup_attribute (container, key)
- attr_reader :start
+ key, rest = pop_key(key)
- def initialize
- @start = Time.now.to_f
- end
+ #value = nil
+ #begin
+ # value = container[key]
+ #rescue Exception => e
+ #end
- #
- # Returns the number of milliseconds since this Timer was
- # instantiated.
- #
- def duration
- (Time.now.to_f - @start) * 1000
- end
- end
+ value = flex_lookup(container, key)
+ return value unless rest
- #
- # (2008.03.12 Deprecated, kept here for a while
- # for backward compatibility)
- #
- # A simple Hash that accepts String or Symbol as lookup keys []
- #
- class SymbolHash < Hash
- def [] (key)
- super(key.to_s)
- end
- end
+ return nil unless value
- #
- # Returns a version of s that is usable as or within a filename
- # (removes for examples things like '/' or '\'...)
- #
- def OpenWFE.ensure_for_filename (s)
+ lookup_attribute(value, rest)
+ end
- s = s.gsub(" ", "_")
- s = s.gsub("/", "_")
- s = s.gsub(":", "_")
- s = s.gsub(";", "_")
- s = s.gsub("\*", "_")
- s = s.gsub("\\", "_")
- s = s.gsub("\+", "_")
- s = s.gsub("\?", "_")
+ #
+ # This method is used within the InFlowWorkItem and the CsvTable classes.
+ #
+ def OpenWFE.has_attribute? (container, key)
- s
- end
+ key, last_key = pop_last_key(key)
- #
- # "my//path" -> "my/path"
- #
- def OpenWFE.clean_path (s)
- s.gsub(/\/+/, "/")
- end
+ container = lookup_attribute(container, key) if key
- #
- # This method is used within the InFlowWorkItem and the CsvTable classes.
- #
- def OpenWFE.lookup_attribute (container, key)
+ if container.respond_to?(:has_key?)
- key, rest = pop_key(key)
+ (container.has_key?(last_key) or container.has_key?(last_key.to_s))
- #value = nil
- #begin
- # value = container[key]
- #rescue Exception => e
- #end
+ elsif container.is_a?(Array) and last_key.is_a?(Fixnum)
- value = flex_lookup(container, key)
+ (last_key < container.length)
- return value unless rest
+ else
- return nil unless value
-
- lookup_attribute(value, rest)
+ false
end
+ end
- #
- # This method is used within the InFlowWorkItem and the CsvTable classes.
- #
- def OpenWFE.has_attribute? (container, key)
+ #
+ # Returns a list of lines matching the pattern in the given file.
+ #
+ # This is also possible :
+ #
+ # OpenWFE::grep "^..) ", "path/to/file.txt" do |line|
+ # puts " - '#{line.downcase}'"
+ # end
+ #
+ # TODO : find a ruby library and use it instead of that code
+ #
+ def OpenWFE.grep (pattern, filepath, &block)
- key, last_key = pop_last_key(key)
+ result = []
+ r = Regexp.new pattern
- container = lookup_attribute(container, key) if key
+ File.open filepath do |file|
+ file.readlines.each do |l|
+ if r.match l
+ if block
+ block.call l
+ else
+ result << l
+ end
+ end
+ end
+ end
+ result unless block
+ end
- if container.respond_to?(:has_key?)
+ #
+ # This method is used within the InFlowWorkItem and the CsvTable classes.
+ #
+ def OpenWFE.set_attribute (container, key, value)
- (container.has_key?(last_key) or container.has_key?(last_key.to_s))
+ i = key.rindex(".")
- elsif container.is_a?(Array) and last_key.is_a?(Fixnum)
-
- (last_key < container.length)
-
- else
-
- false
- end
+ if not i
+ container[key] = value
+ return
end
- #
- # Returns a list of lines matching the pattern in the given file.
- #
- # This is also possible :
- #
- # OpenWFE::grep "^..) ", "path/to/file.txt" do |line|
- # puts " - '#{line.downcase}'"
- # end
- #
- # TODO : find a ruby library and use it instead of that code
- #
- def OpenWFE.grep (pattern, filepath, &block)
+ container = lookup_attribute(container, key[0..i-1])
+ container[key[i+1..-1]] = value
+ end
- result = []
- r = Regexp.new pattern
+ #
+ # This method is used within the InFlowWorkItem and the CsvTable classes.
+ #
+ def OpenWFE.unset_attribute (container, key)
- File.open filepath do |file|
- file.readlines.each do |l|
- if r.match l
- if block
- block.call l
- else
- result << l
- end
- end
- end
- end
- result unless block
+ i = key.rindex(".")
+
+ if not i
+ container.delete key
+ return
end
- #
- # This method is used within the InFlowWorkItem and the CsvTable classes.
- #
- def OpenWFE.set_attribute (container, key, value)
+ container = lookup_attribute container, key[0..i-1]
- i = key.rindex(".")
+ if container.is_a?(Array)
- if not i
- container[key] = value
- return
- end
+ container.delete_at key[i+1..-1].to_i
+ else
- container = lookup_attribute(container, key[0..i-1])
- container[key[i+1..-1]] = value
+ container.delete key[i+1..-1]
end
+ end
- #
- # This method is used within the InFlowWorkItem and the CsvTable classes.
- #
- def OpenWFE.unset_attribute (container, key)
+ #
+ # Returns true if this host is currently online (has access to the web /
+ # internet).
+ #
+ def online?
- i = key.rindex(".")
+ require 'open-uri'
- if not i
- container.delete key
- return
- end
+ begin
+ open("http://www.openwfe.org")
+ true
+ rescue SocketError => se
+ false
+ end
+ end
- container = lookup_attribute container, key[0..i-1]
+ protected
- if container.is_a?(Array)
+ def OpenWFE.pop_key (key)
+ i = key.index(".")
+ return narrow(key), nil unless i
+ [ narrow(key[0..i-1]), key[i+1..-1] ]
+ end
- container.delete_at key[i+1..-1].to_i
- else
+ def OpenWFE.pop_last_key (key)
+ i = key.rindex(".")
+ return nil, narrow(key) unless i
+ [ key[0..i-1], narrow(key[i+1..-1]) ]
+ end
- container.delete key[i+1..-1]
- end
+ def OpenWFE.narrow (key)
+ return 0 if key == "0"
+ i = key.to_i
+ return i if i != 0
+ key
end
#
- # Returns true if this host is currently online (has access to the web /
- # internet).
+ # looks up in a container (something that has a [] method) with a key,
+ # if nothing has been found and the key is a number, turns the
+ # the number into a String a does a last lookup.
#
- def online?
+ def OpenWFE.flex_lookup (container, key)
- require 'open-uri'
+ value = nil
+ begin
+ value = container[key]
+ rescue Exception => e
+ end
+
+ if value == nil and key.kind_of?(Fixnum)
begin
- open("http://www.openwfe.org")
- true
- rescue SocketError => se
- false
+ value = container[key.to_s]
+ rescue Exception => e
end
+ end
+
+ value
end
- protected
-
- def OpenWFE.pop_key (key)
- i = key.index(".")
- return narrow(key), nil unless i
- [ narrow(key[0..i-1]), key[i+1..-1] ]
- end
-
- def OpenWFE.pop_last_key (key)
- i = key.rindex(".")
- return nil, narrow(key) unless i
- [ key[0..i-1], narrow(key[i+1..-1]) ]
- end
-
- def OpenWFE.narrow (key)
- return 0 if key == "0"
- i = key.to_i
- return i if i != 0
- key
- end
-
- #
- # looks up in a container (something that has a [] method) with a key,
- # if nothing has been found and the key is a number, turns the
- # the number into a String a does a last lookup.
- #
- def OpenWFE.flex_lookup (container, key)
-
- value = nil
-
- begin
- value = container[key]
- rescue Exception => e
- end
-
- if value == nil and key.kind_of?(Fixnum)
- begin
- value = container[key.to_s]
- rescue Exception => e
- end
- end
-
- value
- end
-
end