5 ms·
Any examples? I always found it easy to grok but I'm not at a very high level so I'm curious where it gets hairy.
by travbrack 4y ago
Any examples? I always found it easy to grok but I'm not at a very high level so I'm curious where it gets hairy.
- cycomachead 4y agoThere's a bunch of things to pay attention to in Ruby. I wouldn't say these get too hairy, but they trip students up for very understandable reasons. * `a ||= b` is not just `a = a || b`, but `a || a = b` * The distinction between defaults arguments and hash arguments in functional signatures has many edge cases -- but it's much much better in Ruby 3. * There are still 2 pieces of syntax for hashes (`{a: 1}` and `{:a => 1}`) They are the same. * Curly bases show up a fair bit for a language that's not a braces language. :) They're in hashes, blocks, and % strings. e.g. `%w{a b c}` is the same as `%w|a b c|`. They're also used in string interpolation, e.g. `"Hello, #{name}"`. * There are sometimes many ways to do the same thing. There's Procs, blocks, and lambdas. % strings work with many characters. * `unless` for `if not...` and get wonky. * Overusing "surprise if" e.g. `do_thing if other_thing` can be hard to read. * It's so easy to monkey-patch and extend primitive classes, you might not realize when libraries do it. All of these are features that I actually find nice to use in the right contexts. But they can pop up when you don't expect, and they can definitely make Ruby a challenge to learn. That said with a little discipline (or just a linter ;)), I find a lot of Ruby code a joy to read and write.
- greenpeas 4y agoI don't quite get the distinction in your first item: What's the difference between `a = (a || b)` and `a || (a = b)` ?
- Jabbles 4y agoThe rabbithole is here: https://stackoverflow.com/q/995593 https://stackoverflow.com/q/995593
- greenpeas 4y agowow, thanks. I worked with ruby for more than 5 years, and `||=` never surprised me. TLDR On the distinction between `a = (a || b)` and `a || (a = b)`: * There is no difference when `a` and `b` are local variables (unless `a` is undefined, but that's an edge case) * The distinction manifests when `a=` is a method. (It could be a `[]=` or some attr_accessor). Then `a = (a || b)` always invokes `a=`, whereas `a || (a = b)` only invokes `a=` when `a` is falsey. In essence however, `a ||= b` respects the intuitive definition that it sets `a` to `b` if and only if `a` is falsey.
- cycomachead 4y agoYeah, it's not usually an issue in practice. But I do see students get confused trying things out...and it's likely because learning in an interpreter doesn't often look like "real" code does.
- IshKebab 4y ago> `do_thing if other_thing` Yeah I don't get why you would deliberately make the flow control confusing and backwards like that. Python list comprehensions are the same. They make the information flow backwards. This also has the effect of making nesting really confusing.
- greenpeas 4y ago> > `do_thing if other_thing` > Yeah I don't get why you would deliberately make the flow control confusing and backwards like that. I like to use this as function guards, where the first lines in the body of a function can be: return xxx if some_edge_condition? example: https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/activerecord/lib/active_record/relation/merger.rb#L85 https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5b...
- cycomachead 4y agoGuard clauses are great, and when used appropriately clean things up. This is pretty much my only use of the pattern. (Ending boolean-returning methods with a ? is also a great convention in ruby.)
- bobbylarrybobby 4y agoif some_edge_condition: return x
- msbarnett 4y agoI’ve written both professionally and personally found Python makes it harder to see the early out, which makes it less valuable/explicit as a guard. The Ruby pattern is clear up front on what it is rather than being a bag of conditions that you have to get to the end of to discover what they trigger.
- gls2ro 4y agoFor me this fits more into how I think or how I say things in my mind. It might be that I am not an english speaker, but for example when I say to someone a list of instructions I usually say it like this: "Add more water if the dough is dry" and I don't usually say "If the dough is dry add more water" The same for saying for example: "stop mixing if the dough is starting to tear" or "put the bread in the oven when it is ready"