Relaxed rules for Ogg::Vorbis::Comments#merge!.
authorTilman Sauerbeck <tilman@code-monkey.de>
Thu, 7 Sep 2006 16:08:25 +0000 (18:08 +0200)
committerTilman Sauerbeck <tilman@code-monkey.de>
Thu, 7 Sep 2006 16:08:25 +0000 (18:08 +0200)
The method now supports any argument whose each method yields a
key-value pair (array).

Rakefile
ext/comments.c
test/test_main.rb

index e83733c0810112d89109bb4ca3cd93efc89900fd..4aa62fc8f29b4f98a55f0353497792009d1c3773 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -35,9 +35,6 @@ task :extension => [:install, :clobber]
 config = Rake::ConfigureTask.new do |t|
        t.tests << Rake::ConfigureTask::
                   PkgConfigTest.new("vorbis", :is_critical => true)
 config = Rake::ConfigureTask.new do |t|
        t.tests << Rake::ConfigureTask::
                   PkgConfigTest.new("vorbis", :is_critical => true)
-       t.tests << Rake::ConfigureTask::
-                  HaveFuncTest.new("rb_hash_foreach", "ruby.h",
-                                   :is_critical => true)
        t.tests << Rake::ConfigureTask::Gcc4Test.new("gcc4")
 end
 
        t.tests << Rake::ConfigureTask::Gcc4Test.new("gcc4")
 end
 
index fb3ae82f653d727d751cc9975626caabfb1b5f8c..03a237b104f87d0fbfd77f78e165dae2a828fb34 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "vcedit.h"
 
 
 #include "vcedit.h"
 
-static ID id_casecmp, id_replace, id_compare;
+static ID id_casecmp, id_replace, id_each, id_compare;
 
 void
 comments_init (VALUE self, vcedit_state *state)
 
 void
 comments_init (VALUE self, vcedit_state *state)
@@ -345,27 +345,34 @@ c_has_key (VALUE self, VALUE key)
        return Qfalse;
 }
 
        return Qfalse;
 }
 
-static int
-merge_cb (VALUE key, VALUE value, VALUE self)
+static VALUE
+merge_cb (VALUE ar, VALUE self)
 {
 {
-       c_aset (self, key, value);
+       struct RArray *pair = RARRAY (ar);
+
+       c_aset (self, pair->ptr[0], pair->ptr[1]);
 
 
-       return ST_CONTINUE;
+       return Qnil;
 }
 
 /*
  * call-seq:
 }
 
 /*
  * call-seq:
- *  object.merge!(hash) -> object
+ *  object.merge!(arg) -> object
  *
  *
- * Adds the key-value pairs from *hash* to *object*, overwriting existing
+ * Adds the key-value pairs from *arg* to *object*, overwriting existing
  * values if a key already existed in *object*.
  * values if a key already existed in *object*.
+ *
+ * Note that *arg*'s each method needs to yield key-value pairs for this
+ * to work. This means that e.g. hashes and Ogg::Vorbis::Comments objects
+ * are supported as arguments.
  */
 static VALUE
  */
 static VALUE
-c_merge (VALUE self, VALUE hash)
+c_merge (VALUE self, VALUE arg)
 {
 {
-       Check_Type (hash, T_HASH);
+       if (!rb_respond_to (arg, id_each))
+               rb_raise (rb_eArgError, "invalid argument");
 
 
-       rb_hash_foreach (hash, merge_cb, self);
+       rb_iterate (rb_each, arg, merge_cb, self);
 
        return self;
 }
 
        return self;
 }
@@ -536,6 +543,7 @@ Init_Comments (VALUE mVorbis)
 
        id_casecmp = rb_intern ("casecmp");
        id_replace = rb_intern ("replace");
 
        id_casecmp = rb_intern ("casecmp");
        id_replace = rb_intern ("replace");
+       id_each = rb_intern ("each");
        id_compare = rb_intern ("<=>");
 
        return c;
        id_compare = rb_intern ("<=>");
 
        return c;
index 817b59fbb6859784a04d0f2a4d8ad2a46afff5b6..fe622e674a70fd2e1517f595023c40ffc370b04f 100644 (file)
@@ -250,6 +250,14 @@ EOF
                end
        end
 
                end
        end
 
+       def test_merge_bad_arg
+               Ogg::Vorbis::Tagger.open(OGG_FILE) do |t|
+                       assert_raises(ArgumentError) do
+                               t.comments.merge!(42)
+                       end
+               end
+       end
+
        def test_shift
                Ogg::Vorbis::Tagger.open(OGG_FILE) do |t|
                        assert_equal(["artist", "Bolt Thrower"], t.comments.shift)
        def test_shift
                Ogg::Vorbis::Tagger.open(OGG_FILE) do |t|
                        assert_equal(["artist", "Bolt Thrower"], t.comments.shift)