(noob) cast string to array?

K

Koncept

Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

I am not very comfortable with Ruby speak yet, so I hope the
explaination of my problem makes some kind of sense.

I have a program that fetches some results from a shell script. The
result is a string, not a block as it may look like below.

result = { "foobar", "foobar", "foobar" }

I want to basically remove the {}'s and replace them with [] and cast
result as an array so that I can have some fun within Ruby.

I figured something like this:

result = result.sub(/\{/,'[')
result = result.sub(/\}/,']')

Now I have a string that *LOOKS* like and Array but isn't....

Any suggestions are more than welcome.
 
S

Simon Strandgaard

Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

Great.. Welcome to Ruby.

[snip]
result = result.sub(/\{/,'[')
result = result.sub(/\}/,']')

What you has written is the same as (notice the '!' suffix)

result.sub!(/\{/,'[')
result.sub!(/\}/,']')

Above can be chained, so it becomes

result.sub!(/\{/,'[').sub!(/\}/,']')
Any suggestions are more than welcome.

Try 'gsub'

result.gsub!(/\{/,'[').gsub!(/\}/,']')
 
M

Martin Hart

Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

Now I have a string that *LOOKS* like and Array but isn't....

Any suggestions are more than welcome.

irb(main):002:0> s = '["a string", "another string"]'
=> "[\"a string\", \"another string\"]"
irb(main):003:0> array = eval s
=> ["a string", "another string"]
irb(main):004:0> array.class
=> Array


Martin Hart
Arnclan Limited
53 Union Street
Dunstable, Beds
LU6 1EX
http://www.arnclanit.com
 
B

Bermejo, Rodrigo

# sub { block way! }

result.sub!(/\{(.+)\}/) { "["+$1+"]" }

-ronnie.


Simon said:
Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

Great.. Welcome to Ruby.

[snip]

result = result.sub(/\{/,'[')
result = result.sub(/\}/,']')

What you has written is the same as (notice the '!' suffix)

result.sub!(/\{/,'[')
result.sub!(/\}/,']')

Above can be chained, so it becomes

result.sub!(/\{/,'[').sub!(/\}/,']')


Any suggestions are more than welcome.

Try 'gsub'

result.gsub!(/\{/,'[').gsub!(/\}/,']')
 
K

Koncept

Martin Hart said:
irb(main):002:0> s = '["a string", "another string"]'
=> "[\"a string\", \"another string\"]"
irb(main):003:0> array = eval s
=> ["a string", "another string"]
irb(main):004:0> array.class
=> Array

This is great! Thanks Martin. Thanks for all the fast responses as well
everybody.

I just wanted to follow up on some of the responses here:

1) Suggestion to use gsub over sub. I assume that gsub is global?
2) what is the "!" responsible for doing? (Remember me = n00b )
Simon wrote:
result.sub!(/\{/,'[').sub!(/\}/,']')
 
M

Mike Stok

Koncept said:
Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

I am not very comfortable with Ruby speak yet, so I hope the
explaination of my problem makes some kind of sense.

I have a program that fetches some results from a shell script. The
result is a string, not a block as it may look like below.

result = { "foobar", "foobar", "foobar" }

I want to basically remove the {}'s and replace them with [] and cast
result as an array so that I can have some fun within Ruby.

I figured something like this:

result = result.sub(/\{/,'[')
result = result.sub(/\}/,']')

Now I have a string that *LOOKS* like and Array but isn't....

One thing that you might consider is that you have a line which looks
like a CSV data record with { } adound it, so you could use a library
from the Ruby Application Archive to mangle it after you've trimmed the
{ and }.

Alternatively, if the data is "well behaved", you can use a regular
expression to pick it apart. Using irb (interactive ruby to experiment:
=> ["robert", "trey", "adrian", "pat"]

If you're familiar with regular expressions then they are well
integrated into Ruby and can be powerful tools. If you're not then
there have been plenty of other suggestions which may fit your needs.

Hope this helps,

Mike
 
H

Harpo

irb(main):003:0> array = eval s

As the string s comes from the world outside the ruby script, here it is
*supposed* coming from a shell script, it may be dangerous to use eval.
Suppose s is or contains something like :
exec("rm -rf *")
you might run into some problems.
 
S

Stephan Kämper

Koncept said:
1) Suggestion to use gsub over sub. I assume that gsub is global?

Yes, it is. Check your e-version of the pickaxe book (the e-verstion of
"Programming Ruby", Dave thomas & Andy Hunt) for further details.
2) what is the "!" responsible for doing? (Remember me = n00b )

It changes the object the method works on.
I mean

an_obj.gsub( /something/, 'whatever')

will return a new object with the changes applied, but will not change
an_obj, while

an_obj.gsub!( /something/, 'whatever')

will change an_obj.
That's why the ...! methods (aka bang methods) are sometimes called
'destructive'.

Happy Rubying and welcome to the world of Ruby where programming is fun.

Stephan
 
R

Robert Klemme

Simon Strandgaard said:
Hi. What a fantastic language. This is my first day learning using it
and I *love* it so far.

Great.. Welcome to Ruby.

[snip]
result = result.sub(/\{/,'[')
result = result.sub(/\}/,']')

What you has written is the same as (notice the '!' suffix)

result.sub!(/\{/,'[')
result.sub!(/\}/,']')

Above can be chained, so it becomes

result.sub!(/\{/,'[').sub!(/\}/,']')

I always feel unconfortable chaining (g)sub! since the result here *may*
be nil.

I'd rather do

array = eval( result.gsub( /\{([^}]*)\}/, '[\\1]' ) )

robert
 
S

Simon Strandgaard

Simon Strandgaard said:
result.sub!(/\{/,'[')
result.sub!(/\}/,']')

Above can be chained, so it becomes

result.sub!(/\{/,'[').sub!(/\}/,']')

I always feel unconfortable chaining (g)sub! since the result here *may*
be nil.
[snip]

I am curious to when 'nil' may be returned?
 
K

Koncept

Mike said:
One thing that you might consider is that you have a line which looks
like a CSV data record with { } adound it, so you could use a library
from the Ruby Application Archive to mangle it after you've trimmed the
{ and }.

The {} is the result of issuing a command to AppleScript. This is the
way Applescript formats "Lists" or Arrays.
Alternatively, if the data is "well behaved", you can use a regular
expression to pick it apart. Using irb (interactive ruby to experiment:
=> ["robert", "trey", "adrian", "pat"]

Forgive me if I am missing something...

irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

irb(main):004:0> result.class
=> *String*

irb(main):005:0> result = ["robert","trey","adrian","pat"]
=> ["robert", "trey", "adrian", "pat"]

irb(main):006:0> result.class
=> *Array*

Your solution formatted my string to look like an Array, but the result
still has a class of String. :(

How can I cast this String as an Array?
 
R

Robert Klemme

Koncept said:
Mike said:
One thing that you might consider is that you have a line which looks
like a CSV data record with { } adound it, so you could use a library
from the Ruby Application Archive to mangle it after you've trimmed the
{ and }.

The {} is the result of issuing a command to AppleScript. This is the
way Applescript formats "Lists" or Arrays.
Alternatively, if the data is "well behaved", you can use a regular
expression to pick it apart. Using irb (interactive ruby to experiment:
result = '{ "robert", "trey", "adrian", "pat" }'
=> "{ \"robert\", \"trey\", \"adrian\", \"pat\" }"
result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

Forgive me if I am missing something...

irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

irb(main):004:0> result.class
=> *String*

irb(main):005:0> result = ["robert","trey","adrian","pat"]
=> ["robert", "trey", "adrian", "pat"]

irb(main):006:0> result.class
=> *Array*

Your solution formatted my string to look like an Array, but the result
still has a class of String. :(

How can I cast this String as an Array?

What do you think is the type of the result of line 002?

robert

--
Koncept <<
"Contrary to popular belief, the most dangerous animal is not the lion or
tiger or even the elephant. The most dangerous animal is a shark riding
on an elephant, just trampling and eating everything they see." - Jack
Handey
 
S

Simon Strandgaard

Koncept said:
irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]


Try

result = result.scan(/"(.*?)"/).flatten

 
M

Mike Stok

Mike said:
One thing that you might consider is that you have a line which looks
like a CSV data record with { } adound it, so you could use a library
from the Ruby Application Archive to mangle it after you've trimmed the
{ and }.

The {} is the result of issuing a command to AppleScript. This is the
way Applescript formats "Lists" or Arrays.
Alternatively, if the data is "well behaved", you can use a regular
expression to pick it apart. Using irb (interactive ruby to experiment:
result = '{ "robert", "trey", "adrian", "pat" }'
=> "{ \"robert\", \"trey\", \"adrian\", \"pat\" }"
result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

Forgive me if I am missing something...

irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

irb(main):004:0> result.class
=> *String*

irb(main):005:0> result = ["robert","trey","adrian","pat"]
=> ["robert", "trey", "adrian", "pat"]

irb(main):006:0> result.class
=> *Array*

Your solution formatted my string to look like an Array, but the result
still has a class of String. :(

irb was just showing what the value of the expression was. If you want
to apply the technique then either store the result
data = '{ "robert","trey","adrian", "pat" }' => "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"
result = data.scan(/"(.*?)"/).flatten => ["robert", "trey", "adrian", "pat"]
data.class => String
result.class
=> Array

or use it immediately e.g.
got >robert<
got >trey<
got >adrian<
got >pat<
=> ["robert", "trey", "adrian", "pat"]

In general ruby methods don't change object being operated upon unless
they have a "destructive sounding name" (e.g. Array#delete) or end with
a ! (e.g. String#gsub!)

Hope this helps,

Mike
 
M

Martin Hart

irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]

irb(main):004:0> result.class
=> *String*

I think that you are discarding the result of flatten....

(not tested)
array = result.scan(...).flatten
array.class

Cheers,
Martin
 
K

Koncept

Martin Hart said:
I think that you are discarding the result of flatten....

That is exactly what beginners are good at doing. You are absolutely
correct.

Mike's solution worked perfect. It was me that was failing. DOH!
 
R

Robert Klemme

Simon Strandgaard said:
Koncept said:
irb(main):001:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"

irb(main):002:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]


Try

result = result.scan(/"(.*?)"/).flatten


Dunno what you did, but scan returns an array:

irb(main):004:0> result = '{ "robert","trey","adrian", "pat" }'
=> "{ \"robert\",\"trey\",\"adrian\", \"pat\" }"
irb(main):005:0> result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]
irb(main):006:0> result.scan(/"(.*?)"/).flatten.class
=> Array
irb(main):007:0> result = result.scan(/"(.*?)"/).flatten
=> ["robert", "trey", "adrian", "pat"]
irb(main):008:0> result.class
=> Array
irb(main):009:0>

robert
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top