6 ms·
Useless Ruby sugar: Pattern matching
- brightball 3y agoSolid read. Looking forward to part 2. I've been looking for a good deep dive on Ruby's pattern matching after spending a lot of time with Elixir over the past few years. It can make your life a lot easier in many circumstances.
- dpflan 3y agoHa, we "jinxed" eachother on posting about this and Elixir. Given your experience, are you seeing benefits of shared language patterns in multi-language systems at work (e.g. a ruby service, an elixir service, etc)?
- brightball 3y agoIt helps me mentally because I jump back and forth a lot. I've been an Elixir fan for years to the point that it changed the way I think about programming. At the same time, it's really hard even for Elixir to beat a lot of the productivity benefits of Ruby and there's plenty of Ruby-oriented work out there too so I live in both worlds. I write Ruby in a much more functional style now than I previously did, but there are always going to be times when you hit one of those "this would be so much easier in Elixir" moments (not just for Ruby) because there are certain hard things that are just simple in Elixir. Anytime I can utilize some of those techniques in Ruby it lightens my mental load.
- gingerlime 3y ago> At the same time, it's really hard even for Elixir to beat a lot of the productivity benefits of Ruby Can you give an example or explain what you mean?
- brightball 3y agoThat's probably a blog post in and of itself. It's hard to explain but it comes down to a combination of the flexibility and malleability of the language itself, commitment from the community that shows in the tooling and ecosystem among other benefits. It's the closest thing I've seen to Aspect Oriented Programming.
- dpflan 3y agoAnyone using this and anyone using this with an Elixir background? I am curious if programming/language patterns like this, shared across languages, can help teams that have multi-language (eco)systems (e.g. ruby and elixir).
- ezekg 3y agoI don't have an Elixir background (though I envy Elixir in many ways), but I absolutely utilize pattern matching in my Ruby code bases: - https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b263862c9a77296780c45c91c7e90f/lib/typed_params/formatters/jsonapi.rb#L72-L90 https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b26... - https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b263862c9a77296780c45c91c7e90f/lib/typed_params/controller.rb#L116-L123 https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b26... - https://github.com/keygen-sh/keygen-api/blob/36cd61db143cc1c770cf0e4b8e9fb1be63993a3b/app/migrations/adjust_validity_for_validation_codes_migration.rb https://github.com/keygen-sh/keygen-api/blob/36cd61db143cc1c... - https://github.com/keygen-sh/keygen-api/blob/36cd61db143cc1c770cf0e4b8e9fb1be63993a3b/app/policies/release_policy.rb#L10-L26 https://github.com/keygen-sh/keygen-api/blob/36cd61db143cc1c... - https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b263862c9a77296780c45c91c7e90f/spec/typed_params/parameterizer_spec.rb#L6-L32 https://github.com/keygen-sh/typed_params/blob/4e4982b7d2b26... I love it. I want even more pattern matching too, like defp: https://bugs.ruby-lang.org/issues/19764 https://bugs.ruby-lang.org/issues/19764 (with original credit to https://zverok.space/blog/2023-05-05-ruby-types.html https://zverok.space/blog/2023-05-05-ruby-types.html).
- thibaut_barrere 3y agoI use both and I believe pattern matching helps a lot to be more defensive in the programs (verify pre-conditions) and raise accordingly, with a low effort in code.
- hosh 3y agoI wrote Ruby for 10 years and Elixir for about 4. The Ruby version is a bit awkward because it has to make compromises with existing syntax … however, I have already been able to make use of it. My Ruby code these days have gotten a lot more functional, and the type of code I write these days (devops tooling, not Rails code) involves complex transformation or parsing, which makes this useful. I have not tried this with flow control (with :ok and :error tuples) … but I can tell you the missing half missing from this picture are function clauses. (How that would work with being able to redefine functions, I have no idea; just saying though ….) Pattern matching comes all the way from logic programming (Prolog). It should not be surprising that this really shines when working with complex logic.
- phaedryx 3y agoI'm looking forward to this series. I feel like I'm getting "grumpy old man" syndrome with Ruby. I've been using Ruby for long time and I feel like a lot of the changes we get now are more "wouldn't it be cool if..." instead of "this is a really solid, useful addition" changes That said, I do really like how Elixir does some things.
- aardvark179 3y agoI think we now have an, “I worked on a Ruby implementation,” support group at work. I know Java evolves quite slowly, and people complain about it, but I really respect the thought that goes into new Java features.
- ecshafer 3y agoI really cant say i agree here. Ruby has fantastic pattern matching, and is simplifies so much code. I do work for shopify (but unfortunately not on the rails or ruby teams) so maybe a lot of these changes just jive with our culture and company. But why would you not want pattern matching? Ive seen it make pretty huge complicates pieces of code significantly simpler.
- bhaak 3y agoWhat's your opinion on one line method definitions (edit: just learned that those are called endless methods) and numbered block parameters?
- ysavir 3y agoI might also have the "grumpy old man" syndrome, but I'm with you here. But it's not entirely unusual for the languagr. Despite Ruby being great for object oriented programming, it has a lot of features to allow for more functional approaches and other general coding styles. I'm not a fan of it, but if it makes someone happy, good for them. Ruby is meant to be the happy engineering language, so it's all on point. But I'd ask people from refraining from posting these new approaches as the "right way" to do things, as people are apt to do.
- tremon 3y agoAs presented, this one is quite dangerous because it's easy to miss the variable assignment. File.read('data.txt') .split("\n") .map { |ln| some_processing(ln) } .select { |ln| some_filter(ln) } .and_so_on => result I never knew this type of assignment was possible in Ruby, but I will use it if the => var can follow on the next line. A quick test (in 3.1) suggests that it only works with an explicit line continuation: File.read('data.txt') .split("\n") \ => result ...which makes it less appealing. I'll have to try it for a bit to see if I prefer it over the normal `result =` assignment syntax.
- zoogeny 3y agoI have been envious of pattern matching for decades. It is one of those language features I saw (almost certainly in OCaml) and just desired it. I have not worked professionally in any language that supports it. One tiny annoyance I have with many implementations of this feature: # standalone `in` just returns `false` the pattern doesn't match, useful in `if`: if point in [x, y] # it was a 2-element array, and we checked and deconstructed it # ... end This pattern, where `x` and `y` are introduced into the block is a pretty common way to expose a kind of pattern matching guard. You can be sure that inside the `if` block you have valid non-null references to both `x` and `y`. But I hate nesting. In most cases when I am asserting some form of data what I want to do is exit the function if the data is invalid, perhaps with some error code. So what I want is: unless point in [x, y] log.error("Invalid point") return /* ideally some Option/Result */ end # code assuming valid x & y This is one of those "wouldn't it be nice" kinda syntax sugar things, but if I have a series of guards that are progressively narrowing types it ends up feeling much nicer to me.
- twiss 3y agoJakt [1] shares your design philosophy, and has implemented syntax like this: [2] guard foo is Bar(x) else { println("not matched") return -1 as! c_int } println("hello there: {}", x) [1]: https://github.com/SerenityOS/jakt https://github.com/SerenityOS/jakt [2]: https://github.com/SerenityOS/jakt/blob/main/samples/guard/is_guard.jakt https://github.com/SerenityOS/jakt/blob/main/samples/guard/i...
- masklinn 3y agoSwift has that feature as well, restricted to optionals guard let (a, b) = foo else { return whatever } Rust recently, finally, stabilised a full pattern matching version: let Ok((a, b)) = foo else { return whatever; } Although it's been available as a third-party macro (https://crates.io/crates/guard https://crates.io/crates/guard) for years: guard!(let Ok((a, b)) = foo else { return whatever; });
- 3y ago
- sproketboy 3y ago[dead]
- stevebmark 3y agoPattern matching is an objectively good language feature. I wasn't aware the Ruby community sees it as controversial. Why does the Ruby ecosystem do so many things backwards compared to modern software engineering? Pattern matching bad, method_missing good?
- tenderlove 3y agoI didn't know it was controversial either! D:
- ecshafer 3y agoI also work at the small mom and pop e-commerce site, and i havent seen it being considered controversial anywhere. And once people see its benefits i think theve been picking it up. Just this week we had a PR that it serioisly reduced the code by 30% Awesome talk at rails world btw.
- tenderlove 3y agoThank you! Ya, I really enjoy pattern matching. I think new language features just take a long time to percolate through the community. I remember when `->` was controversial, but that's the only way I write lambdas today. :D
- JohnBooty 3y agoPattern matching bad, method_missing good? `method_missing` hasn't been considered good practice in a very long time. i mean, most people never thought it was great, but it's a non-issue IME there are only a few usages of it remaining in activerecord. i thought they were all gone, honestly. (keep in mind about 1/2 of these are tests) https://github.com/search?q=repo%3Arails%2Frails+path%3A%2F%5Eactiverecord%5C%2F%2F+method_missing&type=code https://github.com/search?q=repo%3Arails%2Frails+path%3A%2F%...
- stevebmark 3y agoI guess you haven't read Eloquent Ruby!
- bandyaboot 3y agoReally like that second pattern matching construct that’s cited—for validating/raising an exception on and binding a data structure. Now i’m jealous and wish Python had that.
- Lammy 3y agohttps://docs.ruby-lang.org/en/master/syntax/pattern_matching_rdoc.html https://docs.ruby-lang.org/en/master/syntax/pattern_matching... is worth a read to get a better understanding of the pattern matching capabilities than is conveyed in the various Ruby version announcements that added and expanded it. I'm a big fan of this syntax and use it constantly in my codebase. I also love numbered parameters, endless methods, and Ractors ;)
- Alifatisk 3y agoSo let me get this straight, the purpose for pattern matching in Ruby is to destructure objects easily?