Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hah, as a Pythonista, I'd say it was definitely written by a Rubyist :D

That initial example would usually be, in Python:

  class Stuff:
    def __init__(self):
        self.a_list = [1,2,3,4]
    def __iter__(self):
        for value in self.a_list:
            yield value
Basically, iterators and generators are native constructs that for loop operates on in Python (lists, which are actual "data", are simply special-case optimized instances of those).

Instead of calling iterators/generators "data", I'd call them wrapper control-flow constructs that `for` really operates on which provide amazing syntactic power in Python.

Ruby, from the examples given, seems quite similar, except that the "syntactic sugar" is somewhat inverted. I don't think it makes for a huge difference, but I don't have any Ruby experience.



Or, in Python 3.3 and above:

  class Stuff:
    def __init__(self):
        self.a_list = [1,2,3,4]
    def __iter__(self):
        yield from self.a_list


Can't you just:

    def __iter__(self):
        return iter(self.a_list)


I was not trying to go for the shortest code, but to show idiomatic code where you could easily do something else instead of just returning same values (otherwise, there is no value in wrapping a list with a class at all).

With both `iter(self.a_list)` or `yield from` you'd have to add a list comprehension in there to process each element, and with no Ruby-like blocks in Python, that limits what one can do.

But they are both definitely good approaches to highlight!


You mean generator, not list comprehension. Either way, you wouldn't `yield from` a list comprehension, you'd just use a loop.

E.g. why write:

    yield from (a*2 for a in self.a_list)
When you can:

    for a in self.a_list:
        yield a*2


Exactly, that's the reason I used a loop in the original snippet :)


Author here, I think this would have made the post better for sure, especially to contrast how `yield` does the opposite thing in each language


The article has some misunderstandings about idiomatic ruby imo.

> Ruby keeps going with its methods-first approach, except instead of each we have a new set of methods commonly implemented on collections, as below:

And then you show map, select, etc being re-implemented.

But once you have "each" defined, you'd just include "Enumerable" and get all the others for free.

As a separate point, I almost never implement each on a custom object in ruby. There are probably "library code" cases where it's appropriate, but in day to day work it should be rare. Typically I'd put objects in an ordinary array instead.

Nit: Ruby style guide (and most experienced code I've seen) never uses parens to invoke a method with no args.


    As a separate point, I almost never implement 
    each on a custom object in ruby. There are 
    probably "library code" cases where it's appropriate
Likewise. I've worked with Ruby fulltime since 2014 and never done it in actual project code, only in book exercises, and I'm not sure I've seen it in any gems I've dove into, though I've never poked around in ActiveRecord.

Like you said, I can't think of too many reasons why one would want to implement #each -- on a daily basis I'm just putting various objects into arrays, hashes, etc.

I tend to write very "boring" Ruby. Ruby gives you lots of ways to get wacky, but IMO the default best practice would be to keep it simple and avoid the cute stuff unless you really have a reason.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: