Forum: Ruby on Rails Problem with select and each_with_index

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
925c5035ff3e0005e0604c0cd869b5cf?d=identicon&s=25 ChrisT (Guest)
on 2006-02-28 16:34
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:

<select id="type_typecategory" name="type[typecategory]"><option
value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option></select>

Please point out to an idiot noob where his goof is...
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2006-02-28 20:42
(Received via mailing list)
ChrisT wrote:

> <option value="B">B</option>
> <option value="C">C</option>
> <option value="D">D</option></select>

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.
925c5035ff3e0005e0604c0cd869b5cf?d=identicon&s=25 Chris T (Guest)
on 2006-02-28 21:55
Mark Reginald James wrote:
> ChrisT wrote:
>
>> <option value="B">B</option>
>> <option value="C">C</option>
>> <option value="D">D</option></select>
>
> 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
925c5035ff3e0005e0604c0cd869b5cf?d=identicon&s=25 Chris T (Guest)
on 2006-02-28 23:50
Chris T wrote:
> Mark Reginald James wrote:
>> ChrisT wrote:
>>
>>> <option value="B">B</option>
>>> <option value="C">C</option>
>>> <option value="D">D</option></select>
>>
>> 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.
925c5035ff3e0005e0604c0cd869b5cf?d=identicon&s=25 Chris T (Guest)
on 2006-03-01 00:05
Chris T wrote:
> Chris T wrote:
>> Mark Reginald James wrote:
>>> ChrisT wrote:
>>>
>>>> <option value="B">B</option>
>>>> <option value="C">C</option>
>>>> <option value="D">D</option></select>
>>>
>>> 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).
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2006-03-01 10:19
(Received via mailing list)
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.
925c5035ff3e0005e0604c0cd869b5cf?d=identicon&s=25 Chris T (Guest)
on 2006-03-01 10:49
>>>>> <option value="B">B</option>
>>>>> <option value="C">C</option>
>>>>> <option value="D">D</option></select>
>>>>
>>>> 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.
This topic is locked and can not be replied to.