Problem with select and each_with_index


#1

Disclaimer: Ruby newbie at work

Thought I was going so well. Wanted to produce a select box from an
array constant, with the indices returned as values , and the array
values used as the descriptions. Checked out Ruby RDoc and saw there was
an each_with_index method and came up with:

<%= select (‘type’, ‘typecategory’, Typecategory.each_with_index {|item,
index| [item, index]} )%>

Where typecategory is defined (in environment.rb) as [ ‘A’, ‘B’, ‘C’,
‘D’ ].

What I get out is:

A

B C D

Please point out to an idiot noob where his goof is…


#2

ChrisT wrote:

B C D

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Typecategory.inject([]) { |options, item| options << [item,
options.size] }


We develop, watch us RoR, in numbers too big to ignore.


#3

Mark Reginald J. wrote:

ChrisT wrote:

B C D

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Typecategory.inject([]) { |options, item| options << [item,
options.size] }
Mark

That worked great. Think I only 30% understood why though. Just got the
Pickaxe in the post this afternoon. Will try (with it’s help) to figure
out the other 70%. Thanks for your help.

CT


#4

Chris T wrote:

Mark Reginald J. wrote:

ChrisT wrote:

B C D

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Typecategory.inject([]) { |options, item| options << [item,
options.size] }
Mark

That worked great. Think I only 30% understood why though. Just got the
Pickaxe in the post this afternoon. Will try (with it’s help) to figure
out the other 70%. Thanks for your help.

CT

OK. Have had a quick read of a few of the pages, and I get the inject
method, and like I said this works a treat.

However, still not sure I entirely get why
<%= select (‘type’, ‘typecategory’, Typecategory.each_with_index {|item,
index| [item, index]} )%> fails.
If I do it in the console it outputs what appears to be the right
answer, but doesn’t feed that to select tag. Similarly:
<%= select (‘type’, ‘typecategory’, Typecategory.each_index {|index|
index} )%> fails (gives 0,1,2,3 on command line, but A,B,C,D in select
statement.

Feel free to respond with RTFM (and i will over the next week or so),
but it seems (to a noob) counter-intuitive that it should produce
different responses on command line and in method.


#5

Chris T wrote:

Thinking about this again and re-reading your email, think I’m beginning
to see the light. If I’m understanding it correctly, the fact that
<%= select (‘type’, ‘typecategory’, Typecategory.each {|type| type} )%>
produce a select box feating Typecategory elements is nothing to do with
each runnning through the elements, it’s just acting on Typecategory. In
fact whatevery enumerations are done on typecategory will not change
what comes out (cue dim light-bulb being switched on).

Yes, each_with_index does its work through the side-effects of
evaluating
its block for each array element. It evaluates simply to the array being
operated on. But here you have inline code that you want to return a
value that becomes the option parameter to the select.

You can still use each_with_index, but you must then use more than
one line of code:

<% options = []
Typecategory.each_with_index {|item, index| options << [item,
index]} %>
<%= select :type, :typecategory, options %>


We develop, watch us RoR, in numbers too big to ignore.


#6
B C D

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Typecategory.inject([]) { |options, item| options << [item,
options.size] }
Mark

Thinking about this again and re-reading your email, think I’m beginning
to see the light. If I’m understanding it correctly, the fact that
<%= select (‘type’, ‘typecategory’, Typecategory.each {|type| type} )%>
produce a select box feating Typecategory elements is nothing to do with
each runnning through the elements, it’s just acting on Typecategory. In
fact whatevery enumerations are done on typecategory will not change
what comes out (cue dim light-bulb being switched on).

Also [understanding even better after good night’s sleep – and just in
case anyone else has same problem]:
<%= select (‘type’, ‘typecategory’, Typecategory.each {|type| type} )%>
might as well be written:
<%= select (‘type’, ‘typecategory’, Typecategory)%> because select is
looking for an array and as RDoc explains (when you read it properly):

array.each {|item| block } â?? array # thus returning the original array
whereas:

enum.inject {| memo, obj | block } => obj

gives you a new array (object). Proper understanding at last.


#7

Chris T wrote:

Chris T wrote:

Mark Reginald J. wrote:

ChrisT wrote:

B C D

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Typecategory.inject([]) { |options, item| options << [item,
options.size] }
Mark

That worked great. Think I only 30% understood why though. Just got the
Pickaxe in the post this afternoon. Will try (with it’s help) to figure
out the other 70%. Thanks for your help.

CT

OK. Have had a quick read of a few of the pages, and I get the inject
method, and like I said this works a treat.

However, still not sure I entirely get why
<%= select (‘type’, ‘typecategory’, Typecategory.each_with_index {|item,
index| [item, index]} )%> fails.
If I do it in the console it outputs what appears to be the right
answer, but doesn’t feed that to select tag. Similarly:
<%= select (‘type’, ‘typecategory’, Typecategory.each_index {|index|
index} )%> fails (gives 0,1,2,3 on command line, but A,B,C,D in select
statement.

Feel free to respond with RTFM (and i will over the next week or so),
but it seems (to a noob) counter-intuitive that it should produce
different responses on command line and in method.

each_with_index just evaluates to its argument. Instead you need
to build and return a new array. Something like this should work:

Thinking about this again and re-reading your email, think I’m beginning
to see the light. If I’m understanding it correctly, the fact that
<%= select (‘type’, ‘typecategory’, Typecategory.each {|type| type} )%>
produce a select box feating Typecategory elements is nothing to do with
each runnning through the elements, it’s just acting on Typecategory. In
fact whatevery enumerations are done on typecategory will not change
what comes out (cue dim light-bulb being switched on).