Ruby string to array

For general discussion related FlowStone
Post Reply
stw
Posts: 111
Joined: Tue Jul 13, 2010 11:09 am
Contact:

Ruby string to array

Post by stw »

A question for the Ruby insider...
i save several arrays as a nested array in a text file for later use. E.g.
a = ["1","2","3"]
b = ["4","5","6"]

a,b = [["1", "2", "3"], ["4", "5", "6"]]

I load it back into a ruby module as part of a larger string (text file) and seperate it.
Since it's still a string i just need to convert it back into an array. What seems to be simple gives me some headache :roll:
Is there any easy solution for that?
User avatar
TrojakEW
Posts: 111
Joined: Sat Dec 25, 2010 10:12 am
Location: Slovakia

Re: Ruby string to array

Post by TrojakEW »

Well I don't really understant but do you want to convert

x = [["1", "2", "3"], ["4", "5", "6"]] to ["1", "2", "3","4", "5", "6"]

If ys then just simply use flatten command "x.flatten". If you wish to convert string array to float use "x.flatten.collect { |i| i.to_f }" or i.to_i for integer.
stw
Posts: 111
Joined: Tue Jul 13, 2010 11:09 am
Contact:

Re: Ruby string to array

Post by stw »

No i don't want to flatten it. I even can't because what i load is a string class and not an array class.
The basic problem is to get a multidemensional ruby array back into ruby as an array with the detour of saving it as part of a textfile?
A possible solution could be to do a .split('],') and do some deletes or whatever but i hoped to find a simple method which would do it.
User avatar
TrojakEW
Posts: 111
Joined: Sat Dec 25, 2010 10:12 am
Location: Slovakia

Re: Ruby string to array

Post by TrojakEW »

Make an fsm example to si what you have and what you want.
stw
Posts: 111
Joined: Tue Jul 13, 2010 11:09 am
Contact:

Re: Ruby string to array

Post by stw »

hope this helps to explain it.

string2array prob.fsm
(1.31 KiB) Downloaded 1083 times
User avatar
trogluddite
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby string to array

Post by trogluddite »

Your best way here might be to hi-jack Ruby's own parser - using the 'eval' command.
'eval' takes any string and attempts to parse it as Ruby code, and then runs the code. Like a method call, if the code successfully parses, it also returns the final value. You could use this in several ways...

Code: Select all

x = eval("[[10,20],[20,30]]")   # Put the returned array into x
eval("x = [[10,20],[30,40]]")   # String decides which variable to assign.
eval("x = [[10,20],[30,40]]
      y = [[50,60],[70,80],[90,100]]")  # Evaluate multiple assignments

You have to be very careful with this though - it will attempt to run ANY code that it finds, so you must be sure that your string contains what you want. And NEVER use eval on a user GUI input string without testing the string first for validity- otherwise you have left the door wide open for hacking and crashes (e.g. user types in "sleep" - instant dead plugin!)

One simple safeguard that you should always use is to 'rescue' the code if the string contains any errors- otherwise a faulty string will make Ruby bomb out. Most errors can be caught using a 'plain' rescue - but SyntaxErrors are a special class that always need an explicit 'rescue' of their own...

Code: Select all

begin  # Start an 'error checked' section of code
  # MAIN CODE #
  eval(@myString)
  # MAIN CODE #
rescue SyntaxError  # Recover from syntax errors.
  # CODE # (e.g. set the variable to a default value etc....)
rescue    # Recover from other errors
  # CODE # (e.g. set the variable to a default value etc....)
end   # Return to normal error checking

...that saves you from silly typo's - but not from a 'hacked' string that does contain valid code.
The 'rescue' clauses can also put the error into a variable, so that you can still see the errors while de-bugging your code. The new variable will always have a method '.message' to get you the error message string...

Code: Select all

begin
  eval(@myString)
rescue SyntaxError => error   # Stores the syntax error in the variable 'error'
  output 0, error.message
  # CODE #
rescue => error  # Same for other errors
  output 0, error.message
  # CODE #
end

So 'eval' shouldn't be considered as a 'stock' way to get values from strings because of the caveat's noted above - and also because invoking the Ruby parser is rather slow ('eval' as much of the string as you can all in one go!). But for particularly tricky ones like this, it will save you loads of coding, so long as you can ensure that the string is 'safe'.
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
stw
Posts: 111
Joined: Tue Jul 13, 2010 11:09 am
Contact:

Re: Ruby string to array

Post by stw »

:) Hey Trog,
that's exactly what i need! Saved my day... big thanks!

and thanks for the warnings and backround information!
User avatar
trogluddite
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby string to array

Post by trogluddite »

You're welcome! :D
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
MyCo
Posts: 718
Joined: Tue Jul 13, 2010 12:33 pm
Location: Germany
Contact:

Re: Ruby string to array

Post by MyCo »

If you don't care about the format of your text file, than you can use the "Marshall" object. This way you can store the state of any Ruby object. It's like "serialize" in PHP, but little bit worse to read.
Attachments
string2array Marshall.fsm
(1.23 KiB) Downloaded 1022 times
stw
Posts: 111
Joined: Tue Jul 13, 2010 11:09 am
Contact:

Re: Ruby string to array

Post by stw »

Hi MyCo,
thanks for looking into my example and for answering.
Yes "marshalling" seems to be a good option! Since there's no obvious disadvantage (at least for me :-)) in my case - i'm going to use the whole thing for preset saving and loading - i guess the performance will decide what to use.
My guess is that Marshal should be way faster than the eval parser?

btw: by loading your .fsm i saw that my uploaded example was misleading. By mistake i did my example in the "code/decode trial" submodule :-\ and didn't see that i was still in my "array trial" schematic... Sorry if that was confusing for anyone who took a look into it.
Post Reply