Problem Extracting Array Values

Hi All,

I'm trying to iterate through an array and pull each value into a view
on my Rails app. The array is stored in a MySQL database.

The array is in a varchar (string) column named "blocks" with the value:
["journal", "about", "news"]

I'm trying to pull each value out one at a time.

If I try to access the array with something like this...:
<%= @blocks[0] %>

...the view returns a numeric value:
91

I'm totally confused as to why I can't extract the values out of the
array. It works fine in IRB:
irb(main):004:0> @blocks = ["journal", "about"]
=> ["journal", "about"]
irb(main):005:0> @blocks[0]
=> "journal"
irb(main):006:0>

Is there some reason why I can't get the "journal" string out of the
array?

Thanks in advance for your help!
Dustin

···

--
Posted via http://www.ruby-forum.com/.

As you say, its stored as a String, and String defines to return
the ASCII value of the character
at the given index. If you put 91.chr into IRB you'll see it is the
'[' character.

You need to convert your String into an actual array before you can
access each element.

Maybe:
eval(@blocks)[0]

Cheers
Chris

···

On Apr 4, 10:02 am, Dustin Anderson <rubyfo...@dustinanderson.com> wrote:

Hi All,

I'm trying to iterate through an array and pull each value into a view
on my Rails app. The array is stored in a MySQL database.

The array is in a varchar (string) column named "blocks" with the value:
["journal", "about", "news"]

I'm trying to pull each value out one at a time.

If I try to access the array with something like this...:
<%= @blocks[0] %>

..the view returns a numeric value:
91

I'm totally confused as to why I can't extract the values out of the
array. It works fine in IRB:
irb(main):004:0> @blocks = ["journal", "about"]
=> ["journal", "about"]
irb(main):005:0> @blocks[0]
=> "journal"
irb(main):006:0>

Is there some reason why I can't get the "journal" string out of the
array?

Thanks in advance for your help!
Dustin

--
Posted viahttp://www.ruby-forum.com/.

Dustin Anderson wrote:

Hi All,

I'm trying to iterate through an array and pull each value into a view
on my Rails app. The array is stored in a MySQL database.

Dustin,

For future reference, could you please refer all rails related questions
to the rails forum.

The array is in a varchar (string) column named "blocks" with the value:
["journal", "about", "news"]

I'm trying to pull each value out one at a time.

If I try to access the array with something like this...:
<%= @blocks[0] %>

...the view returns a numeric value:
91

@blocks is not the type you think it is, I am taking a wild stab here
but 91 is the ascii code for "[" so I believe @blocks is a string:

irb(main):007:0> @blocks = "['journal', 'about']"
=> "['journal', 'about']"
irb(main):008:0> @blocks[0]
=> 91
irb(main):009:0>

hope this helps

ilan

···

--
Posted via http://www.ruby-forum.com/\.

That is what I surmised as well. But in general it is a bad idea to be
evaling code from a database. Security and all that.

Dustin, why are you storing those values that way? Why not have a
normalized table with a row for each? In other words you create a
blocks table, define a Block model which belongs_to whatever model you
currently use the blocks column in, and then that model will have many
blocks. Then you could just do @model.blocks.each do |block| in your
view.

Ryan

···

On 4/4/07, ChrisH <chris.hulan@gmail.com> wrote:

As you say, its stored as a String, and String defines to return
the ASCII value of the character
at the given index. If you put 91.chr into IRB you'll see it is the
'[' character.

You need to convert your String into an actual array before you can
access each element.

Maybe:
eval(@blocks)[0]

Dustin, why are you storing those values that way? Why not have a
normalized table with a row for each? In other words you create a
blocks table, define a Block model which belongs_to whatever model you
currently use the blocks column in, and then that model will have many
blocks. Then you could just do @model.blocks.each do |block| in your
view.

Ryan

Thanks Chris, ilan, Ryan for the help... You got it exactly correct.

Ryan - I think you're right - I was storing the value in the database
like that because it's a variable for a Javascript app. I'm writing an
app to allow users to store the state of the view (like Google
personalized homepage or netvibes) and the javascript that I'm using
requires a v to look like this:

value = ["block1_name", "block2_name", "block3_name"]

so, if I store "value" in the database like this, I can just read it
into my javascript. Otherwise, I'll need a helper to construct the
string to look like this.

thanks again.
Dustin

Ps. sorry ilan for posting in the Ruby forum - I thought it was just a
simple ruby array question, but obviously it does have something to do
with Rails.

For the record - the javascript app i'm using for drag/drop portal is
here:
http://aymanh.com/drag-drop-portal-interface-with-scriptaculous

···

--
Posted via http://www.ruby-forum.com/\.

not really

   values = ["block1_name", "block2_name", "block3_name"]

   javascript = "value = #{ values.inspect }"

fyi.

-a

···

On Wed, 4 Apr 2007, Dustin Anderson wrote:

Dustin, why are you storing those values that way? Why not have a
normalized table with a row for each? In other words you create a
blocks table, define a Block model which belongs_to whatever model you
currently use the blocks column in, and then that model will have many
blocks. Then you could just do @model.blocks.each do |block| in your
view.

Ryan

Thanks Chris, ilan, Ryan for the help... You got it exactly correct.

Ryan - I think you're right - I was storing the value in the database
like that because it's a variable for a Javascript app. I'm writing an
app to allow users to store the state of the view (like Google
personalized homepage or netvibes) and the javascript that I'm using
requires a v to look like this:

value = ["block1_name", "block2_name", "block3_name"]

so, if I store "value" in the database like this, I can just read it
into my javascript. Otherwise, I'll need a helper to construct the
string to look like this.

--
be kind whenever possible... it is always possible.
- the dalai lama

unknown wrote:

···

On Wed, 4 Apr 2007, Dustin Anderson wrote:

Thanks Chris, ilan, Ryan for the help... You got it exactly correct.
into my javascript. Otherwise, I'll need a helper to construct the
string to look like this.

not really

   values = ["block1_name", "block2_name", "block3_name"]

   javascript = "value = #{ values.inspect }"

fyi.

-a

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

Thanks

--
Posted via http://www.ruby-forum.com/\.

unknown wrote:

Thanks Chris, ilan, Ryan for the help... You got it exactly correct.
into my javascript. Otherwise, I'll need a helper to construct the
string to look like this.

not really

   values = ["block1_name", "block2_name", "block3_name"]

   javascript = "value = #{ values.inspect }"

fyi.

-a

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

Sure:

>> "block1,block2,block3".split(",")
=> ["block1", "block2", "block3"]

James Edward Gray II

···

On Apr 4, 2007, at 11:05 AM, Dustin Anderson wrote:

On Wed, 4 Apr 2007, Dustin Anderson wrote:

I always thought that Object#inspect could be considered as a (crude) form
of object serialisation, and it would be really useful to have a reverse
"uninspect" operation to recreate the object from it again. Has anyone
written such a parser?

···

On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

Brian Candler wrote:

···

On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

I always thought that Object#inspect could be considered as a (crude) form
of object serialisation, and it would be really useful to have a reverse
"uninspect" operation to recreate the object from it again. Has anyone
written such a parser?

For the basic types, eval will do it to a tolerable degree. For everything else, there's YAML...

--
Alex

irb(main):001:0> a1 = ["foo",/bar/,42,false,nil]
=> ["foo", /bar/, 42, false, nil]
irb(main):002:0> s = a1.inspect
=> "[\"foo\", /bar/, 42, false, nil]"
irb(main):003:0> a2 = eval(s)
=> ["foo", /bar/, 42, false, nil]
irb(main):004:0> a1 == a2
=> true

So:

class String
  def uninspect
    eval(self)
  end
end

:slight_smile:

···

On Apr 4, 11:34 am, Brian Candler <B.Cand...@pobox.com> wrote:

On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:
> is there a simple way in ruby to build an array from a string like this:

> block1,block2,block3 to an array that is like this:

> ["block1", "block2", "block3"]

I always thought that Object#inspect could be considered as a (crude) form
of object serialisation, and it would be really useful to have a reverse
"uninspect" operation to recreate the object from it again. Has anyone
written such a parser?

Brian Candler wrote:

···

On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

I always thought that Object#inspect could be considered as a (crude) form
of object serialisation, and it would be really useful to have a reverse
"uninspect" operation to recreate the object from it again. Has anyone
written such a parser?

There was amarshal (on raa)

http://raa.ruby-lang.org/project/amarshal/

but it may have required you to use eval to go the other way.

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

yeah. maybe

   class String
     def uninspect
       Thread.new {
         $SAFE=4
         begin
           eval self
         rescue Exception => e
           e
         end
       }
     end
   end

though.

-a

···

On Thu, 5 Apr 2007, Phrogz wrote:

On Apr 4, 11:34 am, Brian Candler <B.Cand...@pobox.com> wrote:

On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:

is there a simple way in ruby to build an array from a string like this:

block1,block2,block3 to an array that is like this:

["block1", "block2", "block3"]

I always thought that Object#inspect could be considered as a (crude) form
of object serialisation, and it would be really useful to have a reverse
"uninspect" operation to recreate the object from it again. Has anyone
written such a parser?

irb(main):001:0> a1 = ["foo",/bar/,42,false,nil]
=> ["foo", /bar/, 42, false, nil]
irb(main):002:0> s = a1.inspect
=> "[\"foo\", /bar/, 42, false, nil]"
irb(main):003:0> a2 = eval(s)
=> ["foo", /bar/, 42, false, nil]
irb(main):004:0> a1 == a2
=> true

So:

class String
def uninspect
   eval(self)
end
end

--
be kind whenever possible... it is always possible.
- the dalai lama

No, that's not what I meant.

Firstly, eval is more dangerous than is wanted. For example, "[3, 4]" can
deserialise as [3, 4], but "3 + 4" should give an error as it would never be
the output of foo.inspect

Secondly, it should also handle regular objects with instance variables. For
example,

irb(main):001:0> class Foo; attr_accessor :a, :b, :c; end
=> nil
irb(main):002:0> obj = Foo.new; obj.a="one"; obj.b="two"; obj.c="three"; obj.inspect
=> "#<Foo:0xb7cd6f70 @c=\"three\", @b=\"two\", @a=\"one\">"

That last string would allow an object of class Foo to be reconstructed
(obviously with a different object_id)

Clearly it won't work for graph-like constructs:

irb(main):001:0> a = nil
=> nil
irb(main):002:0> a = [1, 2]
=> [1, 2]
irb(main):003:0> b = [a, a]
=> [[1, 2], [1, 2]]
irb(main):004:0> a << b
=> [1, 2, [[...], [...]]]
irb(main):005:0> b.inspect
=> "[[1, 2, [...]], [1, 2, [...]]]"
irb(main):006:0>

YAML does all that of course, but it's not inspect.

I just think that using 'inspect' would allow basic objects (with simple
nesting) to be stuffed into a database column in a simple and obvious way,
if there were a safe way to reconstruct them from it.

nil
123
"123\n"
[123, "456"]
{"foo"=>["bar","baz"]}
#<Foo: @var="val">

Regards,

Brian.

···

On Thu, Apr 05, 2007 at 02:42:04AM +0900, Alex Young wrote:

Brian Candler wrote:
>On Thu, Apr 05, 2007 at 01:05:44AM +0900, Dustin Anderson wrote:
>>is there a simple way in ruby to build an array from a string like this:
>>
>>block1,block2,block3 to an array that is like this:
>>
>>["block1", "block2", "block3"]
>
>I always thought that Object#inspect could be considered as a (crude) form
>of object serialisation, and it would be really useful to have a reverse
>"uninspect" operation to recreate the object from it again. Has anyone
>written such a parser?
>
For the basic types, eval will do it to a tolerable degree.

Hmm, well maybe it makes a Ruby Quiz then :slight_smile:

···

On Thu, Apr 05, 2007 at 06:25:20AM +0900, Joel VanderWerf wrote:

>I always thought that Object#inspect could be considered as a (crude) form
>of object serialisation, and it would be really useful to have a reverse
>"uninspect" operation to recreate the object from it again. Has anyone
>written such a parser?

There was amarshal (on raa)

http://raa.ruby-lang.org/project/amarshal/

but it may have required you to use eval to go the other way.

I think you failed to properly read my final ":)" as "But of course
you'd be a fool to really use this when so much can go disastrously
wrong by naively running eval() on a String".

Easy to miss the extra whitespace between the eyes and the grin that
implied that. :wink:

···

On Apr 4, 1:17 pm, ara.t.how...@noaa.gov wrote:

On Thu, 5 Apr 2007, Phrogz wrote:
> class String
> def uninspect
> eval(self)
> end
> end

yeah. maybe

   class String
     def uninspect
       Thread.new {
         $SAFE=4
         begin
           eval self
         rescue Exception => e
           e
         end
       }
     end
   end

though.