19 ms·
Code blocks. You don’t use a for loop, you call Array#each. On top of that, Ruby’s Enumerable module allows any object with an each method to access a whole bun
by kayodelycaon 5y ago
Code blocks. You don’t use a for loop, you call Array#each. On top of that, Ruby’s Enumerable module allows any object with an each method to access a whole bunch of convenience methods.
Note, the # means instance method when discussing ruby code. It’s not valid syntax.
Ruby allows you to be extremely concise, while maintaining readability for anyone moderately familiar with the language. In a way Perl is most definitely not.
Short example:
arr = [<blog posts objects>]
# Author may be nil
number_of_authors = arr.map(&:author).compact.uniq.count
You can imagine how easy it is to throw data around with very little code. Loops are abstracted, so you never think about them as loops. Instead you just see data moving around.
Edit: A few languages (like JavaScript) implement this behavior explicitly by passing anonymous functions as callbacks.
- codesections 5y agoThanks, those all seem useful. Assuming I'm following you correctly, Raku already has equivalents to each of those built in: we have code blocks[0], List.map[1] (or `for list -> $el { [codeblock]}`[2] which is a `for` loop, but not a C-style one), and the Iterable/Iterator Roles[3]. So I don't think those features give me any ideas for items to add to the library – but I agree that I'd be sad in a language without them! [0]: https://docs.raku.org/language/control#index-entry-control_flow__blocks-Blocks https://docs.raku.org/language/control#index-entry-control_f... [1]: https://docs.raku.org/routine/map https://docs.raku.org/routine/map [2]: https://docs.raku.org/syntax/for https://docs.raku.org/syntax/for [3]: https://docs.raku.org/language/iterating https://docs.raku.org/language/iterating
- ajuc 5y agoCode blocks are just lambdas though? It's pretty much mainstream these days, even Java and C++ have them. // java equivalent int numberOfAuthors = arr.stream().map(BlogPost::getAuthor).distinct().collect(Collectors.toList()).size(); I happen to think for loops are usually a better choice in languages like Java, but the option is there. EDIT: actually there's a better way, no need to create a list just to count its elements: int numberOfAuthors = arr.stream().map(BlogPost::getAuthor).distinct().collect(Collectors.counting());
- setpatchaddress 5y agoNote how much more concise and yet readable the equivalent Ruby is.
- ajuc 5y agoIf you want to play code golf you can do static imports and write this: int numberOfAuthors = arr.stream().map(getAuthor).distinct().collect(counting()); You still save a few parentheses and one method call in Ruby (.compact vs .stream() and .collect()) and the method names are shorter. Mostly it's a matter of static vs dynamic typing and naming conventions, not a consequence of Ruby code blocks. And is it worth shortening at this point? BTW I know uniq is a thing in unix, but I hate this naming decision.
- cma 5y agoBlocks are a bit different, they can do things like return from the enclosing method. Ultimately I don't think it is worth the complexity and code coloring it adds.
- codesections 5y agoI just saw the code you added; here's a pretty literal translation into Raku in case you're curious (I'm assuming that `<blog posts objects>` is a stand in for omitted code) my @arr = [blog_post_objects]; # Author may be Nil my $author-count = +arr.map(*<author>).grep(*.defined).unique; (Though note that this would only exclude undefined authors. In most situations, I'd probably either know that all defined authors are truthy (e.g., an object) or would want to exclude the falsy ones as well (e.g., empty string). in that case I'd use `.grep(?*)` save a few characters.)
- setpatchaddress 5y agoNot familiar with Raku, but that grep call seems like it would be quite a bit slower than the Ruby equivalent at runtime if it’s anything like a normal grep. Is there some magic there that would make that not so? Edit: clarity
- chrisoverzero 5y ago“grep” is how raku spells what is elsewhere called “filter” or “where”.