From: Skye Shaw!@#$ [mailto:skye.shaw / gmail.com] 
# On Jul 23, 9:10 pm, James Edward Gray II <ja... / grayproductions.net>
# wrote:
# > Another idea is to use String#index() with the optional second  
# > minimum index parameter which you keep incrementing.
# 

cool and simple indeed.

# substr = Proc.new do |s,seq|
#  pos=0
#  index=[]
   ^^^^^
  rename. it might confuse us nubies :)

# 
#  while((i=s.index(seq,pos))!=nil)

simplify. while i=s.index(seq,pos)

#   index<<i
#   pos=i+seq.length
           ^^^^^
       this does not change. init this outside loop.

#  end
# 
#  index
# end


hmmm, even the recursive index method is not bad..

root@pc4all:~# cat -n test.rb
     1  require 'benchmark'
     2  require 'enumerator'
     3
     4  COUNT=100_000
     5
     6  class String
     7    def scan_p ss
     8      a = []
     9      self.scan(ss){a << Regexp.last_match.begin(0)}
    10      a
    11    end
    12
    13    # recursive scan using index
    14    def scan_p2 ss, pos = 0
    15        return [] unless i = index(ss,pos)
    16        [i] + scan_p2(ss, i + ss.length)
    17    end
    18  end
    19
    20  class String
    21     def scan_i seq
    22        pos=0
    23        ndx=[]
    24        slen = seq.length
    25        while i=index(seq,pos)
    26           ndx << i
    27           pos = i + slen
    28        end
    29        ndx
    30     end
    31  end
    32
    33  class String
    34     #substr_positions = Proc.new do |string,substring|
    35     def scan_enum substring
    36        enum_for(:scan, substring).map { $~.offset(0)[0] }
    37     end
    38  end
    39
    40  str="assbasscassmassthatassbass"
    41  seq="ss"
    42
    43  Benchmark.bm do |x|
    44    x.report("with index(): ") do; 1.upto(COUNT) do;
    45     str.scan_i(seq); end end
    46    x.report("with enum_for()/map(): ") do; 1.upto(COUNT) do;
    47     str.scan_enum(seq); end end
    48    x.report("with scan_p(): ") do; 1.upto(COUNT) do; str.scan_p(seq); end end
    49    x.report("with scan_p2(): ") do; 1.upto(COUNT) do; str.scan_p2(seq); end end
    50
    51  end
    52
    53
root@pc4all:~# ruby test.rb
                           user     system      total        real
with index():            4.760000   0.010000   4.770000 (  4.774163)
with enum_for()/map():  22.100000   0.010000  22.110000 ( 22.139630)
with scan_p():          16.680000   0.010000  16.690000 ( 16.702391)
with scan_p2():          9.940000   0.010000   9.950000 (  9.955084)
root@pc4all:~#

not bad at 100k loops :)

root@pc4all:~# cat /proc/cpuinfo | egrep -i '(mhz|name)'
model name      : Pentium II (Klamath)
cpu MHz         : 300.061
root@pc4all:~# cat /proc/meminfo | grep -i mem
MemTotal:       255616 kB
MemFree:          7920 kB

kind regards -botp