

Functional Eye for the Ruby Guy - rjsamson
http://blog.hashrocket.com/posts/functional_eye_ruby_guy

======
pjungwir
I suppose this is a tangent, but a lot of this refactoring strikes me as
obfuscation. Defining methods named `multiple_of_3` and `multiple_of_5` just
to encapsulate a mod? I'd rather just read `x % 3 == 0` and `x % 5 == 0` than
look up a method definition.

And then he makes it worse by throwing those out, defining `multiple_of`, and
using method_missing to make `multiple_of_{3,5}` still work. A big part of
reading unfamiliar code is looking up the implementation of things, and this
is just making it more laborious and confusing.

~~~
martinced
"I'd rather just read x % 3..."

Lots of people don't know of % works. Just as a lot of C / Java / C#
programmers do not know the difference between "if a() & b()" and "if a() &&
b()".

Note that I'm not saying it's great to use "if a() & b()". All I'm saying is
most people do not know the difference.

Try it if you interview people. It's fascinating. And, no, I'm not
disqualifying people if they don't know the difference ; )

~~~
typicalrunt
_Lots of people don't know of % works. Just as a lot of C / Java / C#
programmers do not know the difference between "if a() & b()" and "if a() &&
b()"_

Funny you say that. And incredibly sad too.

I have participated in interviewing many junior/mid/senior developers and you
are correct that they trip up on the % operator. I've also experienced them
tripping up on the word "modulo" and instead trying to calculate the remainder
of a division operation by hand.

While not trying to be elitist, I'm not sure what it says about our industry
when a fundamental concept such as modulus is not understood by programmers.

~~~
dllthomas
That reminds me of a co-worker who was weirded out by my using "modulo" to
mean "except for" or "ignoring" (which is, to my understanding, perfectly
ordinary English).

They did, thankfully, fully understand it in a mathematical context - to my
knowledge I've never worked with someone who didn't, although this and nearby
comments are leaving me wondering...

~~~
pjungwir
I've occasionally tried to work out a sensible rationale for the non-
mathematical meaning based on the mathematical one. Perhaps this is
etymologically unsound, but hey, words are fun. But how do you get from
"remainder when divided by" to "except"? I guess `x % y` gives you "the
leftovers," which is close enough to "except."

~~~
dllthomas
Oh, that's straightforward. In a truly mathematical context, modulo isn't
really an operator per se.

You can say,

10 = 7 modulo 3

Which is kinda, "10 = 7, except someone may have added some number of threes
to each" - so, "10 = 7, but for the threes"

------
gkop
Not sure what version of Ruby 2 the author is using here, but sadly the latest
release candidate defines the using method only in the main scope; it's not
available in a class definition, where he calls it in his example.

------
gfunk911
This doesn't seem to be really utilizing the value of lazy enumerators.

If this was correctly using lazy enumerators, it wouldn't require a range to
be passed in, and you would take values from the resulting lazily evaluated
enumerators until you found one >= 1000. All the laziness does here is prevent
the select from being evaluated until the sum is called.

I don't have 2.0 installed, so this probably has bugs/errors/etc, but I
believe this is what he was going for.

    
    
      module TakeUntil
        refine Enumerator::Lazy do
          def take_until(&b)
            next_obj = take(1).first
            if yield(next_obj)
              []
            else
              [next_obj] + take_until(&b)
            end
          end 
        end
      end
    
      class FunctionalRuby
        using TakeUntil
        def sum_of_multiples_under(max)
          (1..99999999).lazy.select { |x| (x % 3 == 0) || (x % 5 == 0) }.take_until { |x| x > 1000 }.sum
        end
      end
    
      FunctionalRuby.new.sum_of_multiples_under(1000)

