Need a range, but not getting it. . . .

P

Peter Bailey

Hello,
I'm going nuts with the simplest stuff here. I just want to take in
array data and make it into a range.

Here's my test script, called test1.rb:
files = [ARGV]
files.to_s.gsub!(/\-/, "..")
puts files


Here's my attempt, with an argument:
test1.rb im123000-im123006

I get:
im123000-im123006

I want:
im123000..im123006

Thanks,
Peter
 
J

Jon Garvin

Try...

files = [ARGV].to_s
files.gsub!(/\-/, "..")
puts files

However, I *think* that ARGV is already a string? so that to_s in the first line may be redundant.

Your problem was that, although gsub! (with the !) normally modifies the receiver, 'files' wasn't the receiver (to_s was), so you weren't actually changing 'files'.
 
C

ChrisH

Peter said:
Hello,
I'm going nuts with the simplest stuff here. I just want to take in
array data and make it into a range.

Here's my test script, called test1.rb:
files = [ARGV]
files.to_s.gsub!(/\-/, "..")
puts files
....

You need

files = ARGV[0].dup

ARGV is the array of paramaters
[ARGV] is an array with a single element which is also an array

Cheers
 
P

Peter Bailey

Jon said:
Try...

files = [ARGV].to_s
files.gsub!(/\-/, "..")
puts files

However, I *think* that ARGV is already a string? so that to_s in the
first line may be redundant.

Your problem was that, although gsub! (with the !) normally modifies the
receiver, 'files' wasn't the receiver (to_s was), so you weren't
actually changing 'files'.

Cool. That worked, Jon. Thanks. I don't quite understand it, though. I
suppose you're right, that gsub was modifying to_s and not files, but,
why was that? I thought that to_s was modifying files and then gsub was
modifying that modified files. I guess I need to tame my dots, eh?
 
R

Robert Klemme

Hello,
I'm going nuts with the simplest stuff here. I just want to take in
array data and make it into a range.

Here's my test script, called test1.rb:
files = [ARGV]
files.to_s.gsub!(/\-/, "..")
puts files

If you have multiple args, you can do

ARGV[0]..ARGV[1]

Otherwise you can do
a, b = ARGV[0].split('-', 2)
seq = a..b

Cheers

robert
 
R

Robert Klemme

Hello,
I'm going nuts with the simplest stuff here. I just want to take in
array data and make it into a range.

Here's my test script, called test1.rb:
files = [ARGV]
files.to_s.gsub!(/\-/, "..")
puts files

If you have multiple args, you can do

ARGV[0]..ARGV[1]

Otherwise you can do
a, b = ARGV[0].split('-', 2)
seq = a..b

Even more onelinerish

Range.new(*ARGV[0].split('-', 2))

:)

robert
 
P

Peter Bailey

Simon said:
puts ARGV.to_s.gsub(/\-/, '..')

Yup. That certainly works, too. And, that's really simple. I guess I
don't see why making "files = ARGV" throws me off so. I'm just trying to
find the right mind-set for all this.

Cheers and thanks,
Peter
 
P

Peter Bailey

Paul said:
Peter said:
Hello,
I'm going nuts with the simplest stuff here. I just want to take in
array data and make it into a range.

Here's my test script, called test1.rb:
files = [ARGV]

ARGV is an array, not a scalar. you want:

files = ARGV[0]

Or maybe you want to go through the ARGV values one by one.
files.to_s.gsub!(/\-/, "..")
puts files

This code works if you provide a scalar.

Please explain. Will there be more than one value on the command line?

Yes, there may be more than one argument, and, it won't be consistent as
to how many. There could be 3, 4, 5, whatever. That's why I was just
blobbing all of them into ARGV and then trying to break them down from
there.

Thanks.
 
P

Peter Bailey

Paul said:
And it is wrong. "ARGV.to_s" collapses an array into a single string. If
you
provide more than one input argument, you will see the problem.


The "right" mind-set is to process the array one element at a time:

ARGV.each do |arg|
# do something here
end

Thanks, Paul. And, I've tried that:

files = ARGV
files.each do |f|
f = f.to_s
f.gsub!(/-/, "..")
puts f
end

I get a "can't modify frozen string" error message.
 
R

Rimantas Liubertas

Your problem was that, although gsub! (with the !) normally modifies the
receiver, 'files' wasn't the receiver (to_s was), so you weren't actually
changing 'files'.

Not correct. Try it.
files=["im123000-im123006"] => ["im123000-im123006"]
files.to_s.gsub!(/-/,'..') => "im123000..im123006"
files
=> ["im123000-im123006"]


Regards,
Rimantas
 
P

Peter Bailey

Rimantas said:
Your problem was that, although gsub! (with the !) normally modifies the
receiver, 'files' wasn't the receiver (to_s was), so you weren't actually
changing 'files'.

Not correct. Try it.
files=["im123000-im123006"] => ["im123000-im123006"]
files.to_s.gsub!(/-/,'..') => "im123000..im123006"
files
=> ["im123000-im123006"]


Regards,
Rimantas

Thanks. But, I'm trying to design this script for users to put in
arguments. (It's an image modification script that ftps named files
from one server to another.) So, a user might type in: test1.rb
im123456-im123459 im123462 im123466

and, I'd want to capture each of those entries, or series of entries.
So, eventually, yes, I want to get to what you typed in above, but, I
have to decipher the ARGV stuff first.
 
M

Mike Harris

Paul said:
Peter Bailey wrote:

/ ...




1. "f" is already a string, it doesn't need ".to_s".

2. I ran your code without error, Ruby 1.8.4. Are you sure you posted the
same code you are testing?
Why use gsub! at all?

ARGV.each do |f|
puts f.gsub(/-/, "..")
end
 
A

ara.t.howard

Because the original example used a string, and yours uses an array, it is
not a valid counterexample.

Applying ".to_s" to a string has no effect, consequently the receiver is
changed. Applying ".to_s" to anything other than a string makes a copy.

i wounn't quite say that. mmap, for example, simply does some pointer tricks
to return a string. many classes do such things. one should assume only that
to_s returns a string representation of the object, whether or not it's a copy
is class dependant.

regards.

-a
 
A

ara.t.howard

Okay, I agree, but I limited my remark to a string object getting ".to_s"
applied to it, while really, always, has no effect, and returns the
original object. And I see I should have said, "applying '.to_s' to
anything other than a string usually makes a copy."

indeed. i've been bitten the few times it hasn't though! ;-)

-a
 
P

Paul van Delst

Peter said:
Rimantas said:
Your problem was that, although gsub! (with the !) normally modifies the
receiver, 'files' wasn't the receiver (to_s was), so you weren't actually
changing 'files'.
Not correct. Try it.
files=["im123000-im123006"] => ["im123000-im123006"]
files.to_s.gsub!(/-/,'..') => "im123000..im123006"
files
=> ["im123000-im123006"]


Regards,
Rimantas

Thanks. But, I'm trying to design this script for users to put in
arguments. (It's an image modification script that ftps named files
from one server to another.) So, a user might type in: test1.rb
im123456-im123459 im123462 im123466

I had a similar need recently in that I wanted to specify ranges and individual numbers. I
chose the input syntax as
3-10,14,24,26-28
type of thing.

What about this?:

irb(main):016:0> class String
irb(main):017:1> def parse_range #(str)
irb(main):018:2> sa=[]
irb(main):019:2> self.split(",").each do |s|
irb(main):020:3* if s=~/([\w\d]*)-([\w\d]*)/
irb(main):021:4> sa << ($1..$2).to_a
irb(main):022:4> else
irb(main):023:4* sa << s
irb(main):024:4> end
irb(main):025:3> end
irb(main):026:2> pr=sa.flatten.uniq
irb(main):027:2> end
irb(main):028:1> end
=> nil
irb(main):029:0> input
=> "im123456-im123459,im123462,im123466"
irb(main):030:0> input.parse_range
=> ["im123456", "im123457", "im123458", "im123459", "im123462", "im123466"]

Not exactly the same input syntax as you have suggested you want, but close.

cheers,

paulv
 
P

Peter Bailey

Paul said:
Peter Bailey wrote:

/ ...


1. "f" is already a string, it doesn't need ".to_s".

2. I ran your code without error, Ruby 1.8.4. Are you sure you posted
the
same code you are testing?

I ran it again, too, and, I still get the "can't modify frozen string
(TypeError)" error.

On the command line, I typed: test1.rb im123000-im123005, im123007,
im123009
with "test1.rb" being the code above.
 
P

Peter Bailey

Mike said:
Why use gsub! at all?

ARGV.each do |f|
puts f.gsub(/-/, "..")
end

Thanks. Yeh, I can do a "puts," but, I can't just change the silly hypen
to 2 range dots. I get the frozen string error.
 
S

Stefano Crocco

Alle 19:04, gioved=C3=AC 30 novembre 2006, Peter Bailey ha scritto:
Thanks. Yeh, I can do a "puts," but, I can't just change the silly hypen
to 2 range dots. I get the frozen string error.

The point is to use puts, it is to use gsub instead of gsub!, which I see y=
ou=20
used in a previous post. gsub! modifies the string it is called on, which y=
ou=20
can't do with strings in ARGV, since they're frozen. gsub, instead, creates=
a=20
new string, so it shouldn't complain about frozen string.
 
P

Peter Bailey

Paul said:
Peter Bailey wrote:

/ ...


Well, rather than try to sort this out, why not make a copy of the
string
and solve it that way?

Rather than:

f.gsub!(/-/, "..")

Do this:

f = f.gsub(/-/, "..")

BTW there is no purpose to this copy:


Just do:

ARGV.each do |f|


That did it! Here's what I did. I need to not just turn the hyphen into
range dots, but, I also need to get rid of any commas and stuff between
input entries.
ARGV.each do |f|
f = f.gsub(/-/, "..")
f = f.gsub(/,/, "")
puts f
end

So, here's my input:
test1.rb im145000-145004, im145006, im145009

I get:
im45000..im145004
im145006
im145009

Phew. Thanks, everyone. Now I'm going to work on breaking down that
range into its elements, but, I think I can handle that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,219
Messages
2,571,118
Members
47,733
Latest member
BlairMeado

Latest Threads

Top