* An alternative exception is passed as option, eg.
s.constantzie_with_care(Lst,CustomException)
becomes
s.constantzie_with_care(Lst, :exception => CustomException)
* support for :ancestors option
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/CHANGELOG Wed Sep 03 13:29:54 2008 +0200
1.3 @@ -0,0 +1,5 @@
1.4 + * An alternative exception is passed as option, eg
1.5 + s.constantzie_with_care(Lst,CustomException)
1.6 + becomes
1.7 + s.constantzie_with_care(Lst, :exception => CustomException)
1.8 + * support for :ancestors option
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/MIT-LICENSE Wed Sep 03 13:29:54 2008 +0200
2.3 @@ -0,0 +1,20 @@
2.4 +Copyright (c) 2008 Henryk Gerlach
2.5 +
2.6 +Permission is hereby granted, free of charge, to any person obtaining
2.7 +a copy of this software and associated documentation files (the
2.8 +"Software"), to deal in the Software without restriction, including
2.9 +without limitation the rights to use, copy, modify, merge, publish,
2.10 +distribute, sublicense, and/or sell copies of the Software, and to
2.11 +permit persons to whom the Software is furnished to do so, subject to
2.12 +the following conditions:
2.13 +
2.14 +The above copyright notice and this permission notice shall be
2.15 +included in all copies or substantial portions of the Software.
2.16 +
2.17 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2.18 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2.19 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2.20 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
2.21 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2.22 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2.23 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3.1 --- a/README Sun Aug 10 16:21:57 2008 +0200
3.2 +++ b/README Wed Sep 03 13:29:54 2008 +0200
3.3 @@ -2,7 +2,7 @@
3.4
3.5 == License
3.6 Copyright (c) 2008 Henryk Gerach, released under the MIT license
3.7 -see lib/constantize_with_care.rb
3.8 +see MIT-LICENSE
3.9
3.10 == Homepage
3.11 http://www.littleimpact.de/hg/constantize_with_care/
3.12 @@ -17,7 +17,7 @@
3.13 (disrecommended since difficult).
3.14
3.15 If the string is not allowed to be constantized an exception is raised.
3.16 -The +exception+ defaults to RuntimeError and can be overidden.
3.17 +The +exception+ defaults to RuntimeError and can be overidden in the options.
3.18
3.19 The method <tt>constantize_with_care</tt> is added to the String class.
3.20 Instead of <tt>String#constantize</tt> the method
3.21 @@ -35,7 +35,7 @@
3.22
3.23 # For the lazy
3.24 "String".constantize_with_care([String,Fixnum]) #=> String
3.25 - "Float".constantize_with_care([String,Fixnum], Exception) #=> raises Exception
3.26 + "Float".constantize_with_care([String,Fixnum], :exception => Exception) #=> raises Exception
3.27
3.28 # For the daring
3.29 # Everything that starts with S is okay:
4.1 --- a/lib/constantize_with_care.rb Sun Aug 10 16:21:57 2008 +0200
4.2 +++ b/lib/constantize_with_care.rb Wed Sep 03 13:29:54 2008 +0200
4.3 @@ -1,31 +1,34 @@
4.4 # Copyright (c) 2008 Henryk Gerlach
4.5 -#
4.6 -# Permission is hereby granted, free of charge, to any person obtaining
4.7 -# a copy of this software and associated documentation files (the
4.8 -# "Software"), to deal in the Software without restriction, including
4.9 -# without limitation the rights to use, copy, modify, merge, publish,
4.10 -# distribute, sublicense, and/or sell copies of the Software, and to
4.11 -# permit persons to whom the Software is furnished to do so, subject to
4.12 -# the following conditions:
4.13 -#
4.14 -# The above copyright notice and this permission notice shall be
4.15 -# included in all copies or substantial portions of the Software.
4.16 -#
4.17 -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4.18 -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4.19 -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
4.20 -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
4.21 -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
4.22 -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4.23 -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4.24 +# see MIT-LICENSE
4.25 module ConstantizeWithCare
4.26 - def constantize_with_care(allowed_classes, exception="I'm not allowed to constantize \`#{self}'!")
4.27 + def self.included(includer)
4.28 + includer.class_eval do
4.29 + alias :constantize_really_trusted_data :constantize
4.30 + end
4.31 + end
4.32 +
4.33 + # Constantizes the string after checking whether it is allowed to be constantized.
4.34 + #
4.35 + # Options are:
4.36 + # * <tt>:exception</tt> - the exception that should be raised if the string is forbidden (defaults to <tt>RuntimeError</tt>)
4.37 + # * <tt>:ancestors</tt> - <tt>self</tt> may be constantized even if any of its superclasses is contained in <tt>allowed_classes</tt> (defaults to <tt>false</tt>)
4.38 + def constantize_with_care(allowed_classes, options ={})
4.39 + options.reverse_merge!({:exception => "I'm not allowed to constantize \`#{self}'!"})
4.40 ok = false
4.41 - if allowed_classes.respond_to? :include? and allowed_classes.include?(self)
4.42 + if options[:ancestors]
4.43 + self_class = self.constantize
4.44 + if allowed_classes.respond_to? :intersection \
4.45 + and allowed_classes.intersection(self_class.ancestors.map(&:to_s))
4.46 + ok = true
4.47 + end
4.48 + if not ok and (allowed_classes.map(&:to_s) & self_class.ancestors.map(&:to_s)).size > 0
4.49 + ok = true
4.50 + end
4.51 + elsif allowed_classes.respond_to? :include? and allowed_classes.include?(self)
4.52 ok = true
4.53 - elsif not ok and allowed_classes.is_a? Regexp and allowed_classes =~ self
4.54 + elsif allowed_classes.is_a? Regexp and allowed_classes =~ self
4.55 ok = true
4.56 - elsif not ok and allowed_classes.respond_to? :each
4.57 + elsif allowed_classes.respond_to? :each
4.58 allowed_classes.each do |klass|
4.59 if self == klass.to_s
4.60 ok = true
4.61 @@ -33,11 +36,7 @@
4.62 end
4.63 end
4.64 end
4.65 - raise exception unless ok
4.66 - self.constantize
4.67 - end
4.68 -
4.69 - def constantize_really_trusted_data
4.70 + raise options[:exception] unless ok
4.71 self.constantize
4.72 end
4.73 end
5.1 --- a/test/constantize_with_care_test.rb Sun Aug 10 16:21:57 2008 +0200
5.2 +++ b/test/constantize_with_care_test.rb Wed Sep 03 13:29:54 2008 +0200
5.3 @@ -21,11 +21,21 @@
5.4 require "#{File.dirname(__FILE__)}/../lib/constantize_with_care"
5.5 String.send :include, ConstantizeWithCare
5.6
5.7 +class MyException < Exception
5.8 +end
5.9 +
5.10 +class MyParent
5.11 +end
5.12 +
5.13 +class MyKlass < MyParent
5.14 +end
5.15 +
5.16 +class MyChild < MyKlass
5.17 +end
5.18 +
5.19 +
5.20 +
5.21 class ConstantizeWithCareTest< Test::Unit::TestCase
5.22 -
5.23 - class MyException < Exception
5.24 - end
5.25 -
5.26 def test_default_exception
5.27 e = assert_raise(RuntimeError) {
5.28 "Float".constantize_with_care(["String","Fixnum"])
5.29 @@ -35,7 +45,7 @@
5.30
5.31 def test_exception_override
5.32 assert_raise(MyException) {
5.33 - "Float".constantize_with_care(["String","Fixnum"], MyException)
5.34 + "Float".constantize_with_care(["String","Fixnum"], :exception => MyException)
5.35 }
5.36 end
5.37
5.38 @@ -72,4 +82,12 @@
5.39 def test_constantize_really_trusted_data
5.40 assert_equal String, "String".constantize_really_trusted_data
5.41 end
5.42 +
5.43 + def test_ancestors
5.44 + assert_equal "MyKlass".constantize_with_care(["MyParent", "MyException"], :ancestors => true), MyKlass
5.45 + assert_equal "MyKlass".constantize_with_care([MyParent, MyException], :ancestors => true), MyKlass
5.46 + assert_raise(RuntimeError) {
5.47 + "MyKlass".constantize_with_care([MyChild,MyException], :ancestors => true)
5.48 + }
5.49 + end
5.50 end