From: David Flanagan Date: 2007-10-14T15:09:48+09:00 Subject: Another encoding.c patch This is a multi-part message in MIME format. --------------060903010003030704050809 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The attached patch fixes two problems with the new Encoding class. 1) Encoding objects can't be marshaled. So I defined _dump and _load methods. 2) Encoding objects allow dup and clone, but don't define ==, so we have this bad result: e = Encoding.list[0] e == e.dup # => false Also, I find that in irb if I attempt to dup or clone an Encoding object I get this strange error message: TypeError: wrong argument type Encoding (expected Encoding) My patch defines dup and clone methods that always raise TypeError. This means the class shouldn't need an == method. And it prevents, but does not resolve the irb issue. Also attached: test/ruby/test_encoding.rb I hope these are at least a little bit helpful, even though I am a novice at this. David --------------060903010003030704050809 Content-Type: text/plain; name="patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch" Index: encoding.c =================================================================== --- encoding.c (revision 13696) +++ encoding.c (working copy) @@ -498,6 +498,39 @@ return enc_from_encoding(rb_enc_from_index(idx)); } +/* :nodoc: */ +static VALUE +enc_dup(VALUE self) +{ + rb_raise(rb_eTypeError, "can't dup Encoding %s:%s", + rb_obj_classname(self), + rb_enc_name(enc_get_encoding(self))); +} + +/* :nodoc: */ +static VALUE +enc_clone(VALUE self) +{ + rb_raise(rb_eTypeError, "can't clone Encoding %s:%s", + rb_obj_classname(self), + rb_enc_name(enc_get_encoding(self))); +} + +/* :nodoc: */ +static VALUE +enc_dump(int argc, VALUE *argv, VALUE self) +{ + rb_scan_args(argc, argv, "01", 0); + return enc_name(self); +} + +/* :nodoc: */ +static VALUE +enc_load(VALUE klass, VALUE str) +{ + return enc_find(klass,str); +} + void Init_Encoding(void) { @@ -506,4 +539,10 @@ rb_define_method(rb_cEncoding, "name", enc_name, 0); rb_define_singleton_method(rb_cEncoding, "list", enc_list, 0); rb_define_singleton_method(rb_cEncoding, "find", enc_find, 1); + + /* don't allow Encodings to be copied, but do allow marshaling */ + rb_define_method(rb_cEncoding, "dup", enc_dup, 0); + rb_define_method(rb_cEncoding, "clone", enc_clone, 0); + rb_define_method(rb_cEncoding, "_dump", enc_dump, -1); + rb_define_singleton_method(rb_cEncoding, "_load", enc_load, 1); } --------------060903010003030704050809 Content-Type: text/plain; name="test_encoding.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="test_encoding.rb" require 'test/unit' class TestEncoding < Test::Unit::TestCase # Test basic encoding methods: list, find, name def test_encoding encodings = Encoding.list assert_equal(encodings.empty?, false) encodings.each do |e| assert_equal(e, Encoding.find(e.name)) assert_equal(e, Encoding.find(e.name.upcase)) assert_equal(e, Encoding.find(e.name.capitalize)) assert_equal(e, Encoding.find(e.name.downcase)) end end # Test that Encoding objects can't be copied # And that they can be compared by object_id def test_singleton encodings = Encoding.list encodings.each do |e| assert_raise(TypeError) { e.dup } assert_raise(TypeError) { e.clone } assert_equal(e.object_id, Marshal.load(Marshal.dump(e)).object_id) end end end --------------060903010003030704050809--