Forum: Ruby Choice of methods/implementation (was: Writing a game, trying to make dynamic loops)

Aa082c8b00a50928e5860dcd70bf2368?d=identicon&s=25 tamouse mailing lists (Guest)
on 2013-03-25 19:55
(Received via mailing list)
Since otherwise I'd be hijacking, I'm starting a new thread on this:

On Mon, Mar 25, 2013 at 6:52 AM, Robert Klemme
<shortcutter@googlemail.com> wrote:
>
> players = Integer(gets).times.map do |i|
>     puts "Name of player #{n+1}?"
>     Player.new(gets.chomp)
>   end


Could you say why, Robert? Obviously there's more than one way to do
something, but I am interested in why you'd choose this way?

I don't very much like the previous Array.new() {} either, although
being 1-based might be easier for some to understand, but breaks my
oh-so-long-established zero-based array mentality. I'd have approached
this with #reduce. I'd appreciate hearing your thoughts on the
trade-offs.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-25 23:04
(Received via mailing list)
On Mon, Mar 25, 2013 at 7:55 PM, tamouse mailing lists
<tamouse.lists@gmail.com> wrote:
>>>   Player.new(gets.chomp)
>>> end
>>
>> I'd rather use #times with #map:
>>
>> players = Integer(gets).times.map do |i|
>>     puts "Name of player #{n+1}?"
>>     Player.new(gets.chomp)
>>   end

I just notice, there is a typo in the name prompt.  Should have been

puts "Name of player #{i+1}?"

> Could you say why, Robert? Obviously there's more than one way to do
> something, but I am interested in why you'd choose this way?

Oh, it's probably rather a matter of taste.  When the "automatic"
to_enum was introduced for block methods which were called without a
block I took on the habit of using that feature since I find it
elegant.  There's absolutely nothing wrong with your solution.  In
fact, it might be a more efficient.

I'd just point out that using Integer() is more robust than
String#to_i because it will ensure the argument *is* actually a String
representing an integer.

> I don't very much like the previous Array.new() {} either, although
> being 1-based might be easier for some to understand, but breaks my
> oh-so-long-established zero-based array mentality. I'd have approached
> this with #reduce. I'd appreciate hearing your thoughts on the
> trade-offs.

Which previous Array.new {} do you mean?  The one with the separate
counter variable?

I don't think this calls for #inject / #reduce.  IMHO #map is a better
choice here since you do not need to explicitly deal with the Array
copied into.

Kind regards

robert
87e61e351b823e19b4a62a896d2af0d4?d=identicon&s=25 Henry Maddocks (Guest)
on 2013-03-26 01:05
(Received via mailing list)
On 26/03/2013, at 11:04 AM, Robert Klemme <shortcutter@googlemail.com>
wrote:

> choice here since you do not need to explicitly deal with the Array
> copied into.

I like to think of 'reduce' meaning you have several things that you
want to reduce to a single thing whereas with 'map' you are mapping one
thing to another thing, e.g. mapping integers to players.

Henry
Aa082c8b00a50928e5860dcd70bf2368?d=identicon&s=25 tamouse mailing lists (Guest)
on 2013-03-26 06:12
(Received via mailing list)
On Mon, Mar 25, 2013 at 5:04 PM, Robert Klemme
<shortcutter@googlemail.com> wrote:
>>>>   Player.new(gets.chomp)
>
>
> I'd just point out that using Integer() is more robust than
> String#to_i because it will ensure the argument *is* actually a String
> representing an integer.

That is interesting -- I will probably try that more often.

>> I don't very much like the previous Array.new() {} either, although
>> being 1-based might be easier for some to understand, but breaks my
>> oh-so-long-established zero-based array mentality. I'd have approached
>> this with #reduce. I'd appreciate hearing your thoughts on the
>> trade-offs.
>
> Which previous Array.new {} do you mean?  The one with the separate
> counter variable?

In this case, it was in the solution proposed by Hans, one message up
from yours.

> I don't think this calls for #inject / #reduce.  IMHO #map is a better
> choice here since you do not need to explicitly deal with the Array
> copied into.

Very good point. I may have started thinking of #reduce as a big
hammer that can be used everywhere. :)

Thank you!
Aa082c8b00a50928e5860dcd70bf2368?d=identicon&s=25 tamouse mailing lists (Guest)
on 2013-03-26 06:22
(Received via mailing list)
On Mon, Mar 25, 2013 at 7:03 PM, Henry Maddocks <hmaddocks@me.com>
wrote:
>> counter variable?
>>
>> I don't think this calls for #inject / #reduce.  IMHO #map is a better
>> choice here since you do not need to explicitly deal with the Array
>> copied into.
>
>
> I like to think of 'reduce' meaning you have several things that you want to
> reduce to a single thing whereas with 'map' you are mapping one thing to
> another thing, e.g. mapping integers to players.

I do probably overuse #reduce, as I find those things elegant. But I
do sometimes forget about the #map part of the Map Reduce pattern. I'm
getting better though! I recently recoded something from this:

names = items.reduce([]) {|m,i| m << i.name}

to this:

names = items.map(&:name)
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-26 08:41
(Received via mailing list)
On Tue, Mar 26, 2013 at 6:11 AM, tamouse mailing lists
<tamouse.lists@gmail.com> wrote:
> On Mon, Mar 25, 2013 at 5:04 PM, Robert Klemme
> <shortcutter@googlemail.com> wrote:

>> I don't think this calls for #inject / #reduce.  IMHO #map is a better
>> choice here since you do not need to explicitly deal with the Array
>> copied into.
>
> Very good point. I may have started thinking of #reduce as a big
> hammer that can be used everywhere. :)

A while ago I went through that phase as well... :-)

On Tue, Mar 26, 2013 at 6:20 AM, tamouse mailing lists
<tamouse.lists@gmail.com> wrote:
> On Mon, Mar 25, 2013 at 7:03 PM, Henry Maddocks <hmaddocks@me.com> wrote:

>> I like to think of 'reduce' meaning you have several things that you want to
>> reduce to a single thing whereas with 'map' you are mapping one thing to
>> another thing, e.g. mapping integers to players.

Yeah, but in this case mapping one collection onto another one is a
superior abstraction because it forces one to do less mechanics. :-)

> I do probably overuse #reduce, as I find those things elegant.

It is.  Basically you can implement almost all methods of Enumerable
with #inject.  I think I did this once for fun.

> But I
> do sometimes forget about the #map part of the Map Reduce pattern. I'm
> getting better though! I recently recoded something from this:
>
> names = items.reduce([]) {|m,i| m << i.name}
>
> to this:
>
> names = items.map(&:name)

Thumbs up!

Kind regards

robert
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.