Ruby equiv of perl pos

Or to be more exact, how would I do the following in ruby?

while ($string =~ /\0/g) {
$new_string .= sprintf ‘%o’, (pos $string) - 1;
}

snacktime ha escrito:

Or to be more exact, how would I do the following in ruby?

while ($string =~ /\0/g) {
$new_string .= sprintf ‘%o’, (pos $string) - 1;
}

#!/usr/bin/env ruby

new_string = ‘’
string = “\0\0\0asda\0\0\0sdasd”

pos = 0
while pos = string.index( /\0/, pos )
match = Regexp.last_match
pos += match.size
new_string << ‘%o’ % (pos - 1)
end

puts new_string

$ ri -T IO#pos
----------------------------------------------------------------- IO#pos
ios.pos => integer
ios.tell => integer

  Returns the current offset (in bytes) of ios.

     f = File.new("testfile")
     f.pos    #=> 0
     f.gets   #=> "This is line one\n"
     f.pos    #=> 17

James Edward G. II

snacktime wrote:

Or to be more exact, how would I do the following in ruby?

while ($string =~ /\0/g) {
$new_string .= sprintf ‘%o’, (pos $string) - 1;
}

Another idea:

string = “one\0two\0threeeeeee\0”
result = ‘’
string.scan(/\0/) do
result << ‘%o’ % $`.length
end
puts result #=> \3\7\22

Robin

Another idea:

string = “one\0two\0threeeeeee\0”
result = ‘’
string.scan(/\0/) do
result << ‘%o’ % $`.length
end

This is simpler to write, but will be slower on longer strings.

#!/usr/bin/env ruby

@string = “\0\0\0asda\0\0\0sdasd” * 5000

def test_a
result = ‘’
pos = 0
while pos = @string.index( /\0/, pos )
match = Regexp.last_match
pos += match.size
result << ‘%o’ % (pos - 1)
end
return result
end

def test_b
result = ‘’
@string.scan(/\0/) do
result << ‘%o’ % $`.length
end
return result
end

require ‘benchmark’

Benchmark.benchmark() { |x|
x.report(‘a:’) { test_a }
x.report(‘b:’) { test_b }
}

Thanks guys. I’m having to write a module to set parity on strings.
I’ll post it when I’m done, maybe someone can help clean it
up/refactor it a bit and put it on rubyforge or something. Not sure
how much demand there is for something like this.

gga wrote:

This is simpler to write, but will be slower on longer strings.

You’re right, it’s much slower! I didn’t think about speed while writing
it, thanks for pointing it out.

Another question: Why do you use Regexp.last_match? Maybe to have a more
general solution? The following seems to be simpler and faster:

def test_b
result = ‘’
pos = 0
while pos = @string.index("\0", pos)
result << ‘%o’ % pos
pos += 1
end
return result
end

Robin S. ha escrito:

Another question: Why do you use Regexp.last_match? Maybe to have a more
general solution?

Yes. That way you can use any sort of regexp, not just a single
character match.

On Aug 12, 2006, at 4:33 PM, snacktime wrote:

Or to be more exact, how would I do the following in ruby?

while ($string =~ /\0/g) {
$new_string .= sprintf ‘%o’, (pos $string) - 1;
}

if perldoc -f pos is describing what pos does in this case,

new_string = “”
while pos = string =~ /\0/g
new_string << “%o” % (pos - 1)
end

Logan C. ha escrito:

if perldoc -f pos is describing what pos does in this case,

new_string = “”
while pos = string =~ /\0/g
new_string << “%o” % (pos - 1)
end

This won’t work. Regexp in ruby does not support Perl’s /g option.
You need to use String.index() with a position modifier as I showed
before or gsub in case of a global regexp replacement.

Logan C. ha escrito:

How about:

new_string = “”
string.scan(/\0/) do |m|
new_string = “%o” % $~.offset(0).first
end

That should work okay (well, it should be new_string << …, thou).
I’ll admit I was unaware of MatchData’s offset method. That’s cool.
Using string.scan() should be only slightly slower than the
while/index() loop do to the inherent yield in scan {}.
If you are comming from Perl, I would also recommend to stick with
Regexp.last_match instead of $~ for clarity. I did 5+ years of Perl
but I’ll be damned if I remember what all the $symbol vars stand for
without looking them up.

On Aug 13, 2006, at 3:40 PM, gga wrote:

This won’t work. Regexp in ruby does not support Perl’s /g option.
You need to use String.index() with a position modifier as I showed
before or gsub in case of a global regexp replacement.

Oops, out of practice with my perl. Forgot that /g with a while loop
was how you did #scan { } in perl.

How about:

new_string = “”
string.scan(/\0/) do |m|
new_string = “%o” % $~.offset(0).first
end

On Mon, 14 Aug 2006 14:20:10 +0900, you wrote:

I’ll admit I was unaware of MatchData’s offset method. That’s cool.
Using string.scan() should be only slightly slower than the
while/index() loop do to the inherent yield in scan {}.
If you are comming from Perl, I would also recommend to stick with
Regexp.last_match instead of $~ for clarity. I did 5+ years of Perl
but I’ll be damned if I remember what all the $symbol vars stand for
without looking them up.

http://home.cogeco.ca/~tsummerfelt1
ROVING SWARM: Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos
telnet://ventedspleen.dyndns.org

On Mon, 14 Aug 2006 14:20:10 +0900, you wrote:

new_string = “”
string.scan(/\0/) do |m|
new_string = “%o” % $~.offset(0).first
end

That should work okay

i noticed that all the ruby solutions presented were longer than the
original perl code. i found the perl code more readable… which is
unusual for most perl-ruby comparisons :slight_smile:

http://home.cogeco.ca/~tsummerfelt1
ROVING SWARM: Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos
telnet://ventedspleen.dyndns.org

tony summerfelt wrote:

i noticed that all the ruby solutions presented were longer than the
original perl code. i found the perl code more readable… which is
unusual for most perl-ruby comparisons :slight_smile:

Well, I wouldn’t consider it unusual for the code to be longer when you
are trying to duplicate the functionality of a keyword of another
language that doesn’t exist in Ruby!

Perhaps if String#scan made MatchData objects available as requested
here: RCR 276: Make String#scan, #gsub, and #sub yield MatchData objects the Ruby solution would be
cleaner.

  • Mark.