[前][次][番号順一覧][スレッド一覧]

ruby-changes:11918

From: shyouhei <ko1@a...>
Date: Tue, 26 May 2009 21:06:39 +0900 (JST)
Subject: [ruby-changes:11918] Ruby:r23581 (ruby_1_8_7): merge revision(s) 22332:

shyouhei	2009-05-26 21:06:21 +0900 (Tue, 26 May 2009)

  New Revision: 23581

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23581

  Log:
    merge revision(s) 22332:
    * lib/ostruct.rb (OpenStruct#new_ostruct_member): checks if frozen.
      [ruby-talk:328195], [ruby-core:22142]

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/lib/ostruct.rb
    branches/ruby_1_8_7/test/ostruct/test_ostruct.rb
    branches/ruby_1_8_7/version.h

Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 23580)
+++ ruby_1_8_7/ChangeLog	(revision 23581)
@@ -1,3 +1,8 @@
+Tue May 26 21:02:13 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/ostruct.rb (OpenStruct#new_ostruct_member): checks if frozen.
+	  [ruby-talk:328195], [ruby-core:22142]
+
 Tue May 26 21:00:08 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/ostruct.rb (OpenStruct#inspect): fixed the recursion check.
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 23580)
+++ ruby_1_8_7/version.h	(revision 23581)
@@ -2,7 +2,7 @@
 #define RUBY_RELEASE_DATE "2009-05-26"
 #define RUBY_VERSION_CODE 187
 #define RUBY_RELEASE_CODE 20090526
-#define RUBY_PATCHLEVEL 162
+#define RUBY_PATCHLEVEL 163
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
Index: ruby_1_8_7/lib/ostruct.rb
===================================================================
--- ruby_1_8_7/lib/ostruct.rb	(revision 23580)
+++ ruby_1_8_7/lib/ostruct.rb	(revision 23581)
@@ -67,28 +67,33 @@
     @table.each_key{|key| new_ostruct_member(key)}
   end
 
+  def modifiable
+    if self.frozen?
+      raise TypeError, "can't modify frozen #{self.class}", caller(2)
+    end
+    @table
+  end
+  protected :modifiable
+
   def new_ostruct_member(name)
     name = name.to_sym
     unless self.respond_to?(name)
-      meta = class << self; self; end
-      meta.send(:define_method, name) { @table[name] }
-      meta.send(:define_method, :"#{name}=") { |x| @table[name] = x }
+      class << self; self; end.class_eval do
+        define_method(name) { @table[name] }
+        define_method("#{name}=") { |x| modifiable[name] = x }
+      end
     end
+    name
   end
 
   def method_missing(mid, *args) # :nodoc:
     mname = mid.id2name
     len = args.length
-    if mname =~ /=$/
+    if mname.chomp!('=')
       if len != 1
         raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
       end
-      if self.frozen?
-        raise TypeError, "can't modify frozen #{self.class}", caller(1)
-      end
-      mname.chop!
-      self.new_ostruct_member(mname)
-      @table[mname.intern] = args[0]
+      modifiable[new_ostruct_member(mname)] = args[0]
     elsif len == 0
       @table[mid]
     else
Index: ruby_1_8_7/test/ostruct/test_ostruct.rb
===================================================================
--- ruby_1_8_7/test/ostruct/test_ostruct.rb	(revision 23580)
+++ ruby_1_8_7/test/ostruct/test_ostruct.rb	(revision 23581)
@@ -2,6 +2,21 @@
 require 'ostruct'
 
 class TC_OpenStruct < Test::Unit::TestCase
+  def assert_not_respond_to(object, method, message="")
+    _wrap_assertion do
+      full_message = build_message(message, <<EOT, object, object.class, method)
+<?>
+of type <?>
+expected not to respond_to\\?<?>.
+EOT
+      _wrap_assertion do
+        if object.respond_to?(method)
+          raise Test::Unit::AssertionFailedError, full_message, caller(5)
+        end
+      end
+    end
+  end
+
   def test_equality
     o1 = OpenStruct.new
     o2 = OpenStruct.new
@@ -34,4 +49,12 @@
     foo.bar.foo = foo
     assert_equal('#<OpenStruct bar=#<OpenStruct foo=#<OpenStruct ...>>>', foo.inspect)
   end
+
+  def test_frozen
+    o = OpenStruct.new
+    o.a = 'a'
+    o.freeze
+    assert_raise(TypeError) {o.b = 'b'}
+    assert_not_respond_to(o, :b)
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]