Feature #8853 ยป string-sub-enumerator.patch
| string.c | ||
|---|---|---|
| 
      *  call-seq: 
   | 
||
| 
      *     str.sub!(pattern, replacement)          -> str or nil 
   | 
||
| 
      *     str.sub!(pattern) {|match| block }      -> str or nil 
   | 
||
| 
      *     str.sub!(pattern)                       -> enumerator 
   | 
||
| 
      * 
   | 
||
| 
      *  Performs the same substitution as String#sub in-place. 
   | 
||
| 
      * 
   | 
||
| 
      *  Returns +str+ if a substitution was performed or +nil+ if no substitution 
   | 
||
| 
      *  was performed. 
   | 
||
| 
      *  was performed.  If no block and no <i>replacement</i> is given, an 
   | 
||
| 
      *  enumerator is returned instead. 
   | 
||
| 
      */ 
   | 
||
| 
     static VALUE 
   | 
||
| ... | ... | |
| 
         int iter = 0; 
   | 
||
| 
         int tainted = 0; 
   | 
||
| 
         long plen; 
   | 
||
| 
         int min_arity = rb_block_given_p() ? 1 : 2; 
   | 
||
| 
         long beg; 
   | 
||
| 
         rb_check_arity(argc, min_arity, 2); 
   | 
||
| 
         rb_check_arity(argc, 1, 2); 
   | 
||
| 
         if (argc == 1) { 
   | 
||
| 
             RETURN_ENUMERATOR(str, argc, argv); 
   | 
||
| 
     	iter = 1; 
   | 
||
| 
         } 
   | 
||
| 
         else { 
   | 
||
| ... | ... | |
| 
      *     str.sub(pattern, replacement)         -> new_str 
   | 
||
| 
      *     str.sub(pattern, hash)                -> new_str 
   | 
||
| 
      *     str.sub(pattern) {|match| block }     -> new_str 
   | 
||
| 
      *     str.sub(pattern)                      -> enumerator 
   | 
||
| 
      * 
   | 
||
| 
      *  Returns a copy of +str+ with the _first_ occurrence of +pattern+ 
   | 
||
| 
      *  replaced by the second argument. The +pattern+ is typically a Regexp; if 
   | 
||
| ... | ... | |
| 
      *  <code>$&</code>, and <code>$'</code> will be set appropriately. The value 
   | 
||
| 
      *  returned by the block will be substituted for the match on each call. 
   | 
||
| 
      * 
   | 
||
| 
      *  When neither a block nor a second argument is supplied, an 
   | 
||
| 
      *  Enumerator is returned. 
   | 
||
| 
      * 
   | 
||
| 
      *  The result inherits any tainting in the original string or any supplied 
   | 
||
| 
      *  replacement string. 
   | 
||
| 
      * 
   | 
||
| ... | ... | |
| 
     static VALUE 
   | 
||
| 
     rb_str_sub(int argc, VALUE *argv, VALUE str) 
   | 
||
| 
     { 
   | 
||
| 
         VALUE ret; 
   | 
||
| 
         str = rb_str_dup(str); 
   | 
||
| 
         rb_str_sub_bang(argc, argv, str); 
   | 
||
| 
         ret = rb_str_sub_bang(argc, argv, str); 
   | 
||
| 
         if (argc == 1 && !rb_block_given_p()) { 
   | 
||
| 
             return ret; 
   | 
||
| 
         } 
   | 
||
| 
         return str; 
   | 
||
| 
     } 
   | 
||
| test/ruby/test_string.rb | ||
|---|---|---|
| 
         assert_nil(a.sub!(S('X'), S('Y'))) 
   | 
||
| 
       end 
   | 
||
| 
       def test_sub_enumerator 
   | 
||
| 
         enum = 'abc'.sub("b") 
   | 
||
| 
         assert_equal("b", enum.next) 
   | 
||
| 
         assert_raise(StopIteration) { enum.next } 
   | 
||
| 
         str = 'abc' 
   | 
||
| 
         enum = str.sub!("b") 
   | 
||
| 
         enum.feed 'z' 
   | 
||
| 
         assert_equal("b", enum.next) 
   | 
||
| 
         assert_raise(StopIteration) { enum.next } 
   | 
||
| 
         assert_equal("azc", str) 
   | 
||
| 
       end 
   | 
||
| 
       def test_sub_hash 
   | 
||
| 
         assert_equal('azc', 'abc'.sub(/b/, "b" => "z")) 
   | 
||
| 
         assert_equal('ac', 'abc'.sub(/b/, {})) 
   | 
||