Bugs item #4391, was opened at 2006-05-08 22:34
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=4391&group_id=426

Category: Standard Library
Group: None
Status: Open
Resolution: None
Priority: 3
Submitted By: Nicola Piccinini (pic)
Assigned to: Nobody (None)
Summary: buggy tr_s in jcode

Initial Comment:
tr_s doesn't work as expected:

$ irb
irb(main):001:0> "hello".tr_s('el','*')
=> "h*o"
irb(main):002:0> require 'jcode'
=> true
irb(main):003:0> "hello".tr_s('el','*')
=> "he*o"
irb(main):004:0> quit
$ ruby -v
ruby 1.8.4 (2005-12-24) [i486-linux]

I'm a newbie in Ruby world, anyway I wrote a "patch" and relative tests for better explaining the problem:

#- "patch" -----------------------------------------
require 'jcode'
class String
  
  # dirty trick:
  # transforms {'e' => '*, 'l' => '*'} to { 'e' => '*'} and
  # call self.tr!('l','e')
  def __adjust_values_repetitions_for_tr_s(h)
    v = {}
    h.each_key do |k|
      if v.has_key?(h[k])
        self.tr!(k, v[h[k]])
        h.delete(k)  
      else
        v[h[k]] = k
      end    
    end
  end
    
  private :__adjust_values_repetitions_for_tr_s

  def tr_s!(from, to)
    return self.delete!(from) if to.length == 0

    # pattern = SqueezePatternCache[from] ||= /([#{_regex_quote(from)}])\1+/
    pattern = SqueezePatternCache[from] ||= /([#{_regex_quote(from)}])\1*/
    if from[0] == ?^
      last = /.$/.match(to)[0]
      self.gsub!(pattern, last)
    else
      h = HashCache[from + "1-0" + to] ||= expand_ch_hash(from, to)
      __adjust_values_repetitions_for_tr_s(h)
      self.gsub!(pattern) do h[$1] end
    end
  end
end

#- test --------------------------------------------

require 'test/unit'

class JcodePatchTest < Test::Unit::TestCase
  def test_tr_s
    assert_equal('hero', "hello".tr_s('l','r'))
    assert_equal('h*o', "hello".tr_s('el','*'))
    assert_equal('hhxo', "hello".tr_s('el','hx'))
    assert_equal('tru*ero*ero*', "trullalerolerola".tr_s('al','*'))
    assert_equal('trualaeroaeroal', "trullalerolerola".tr_s('al','la'))
    assert_equal('trurtrerorerort', "trullalerolerola".tr_s('al','tr'))
    assert_equal('t*u*e*e*', "trullalerolerola".tr_s('alro','*'))
    assert_equal('t*u*', "trullalerolerola".tr_s('alero','*'))
  end
end


----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=4391&group_id=426