Ruby's exceptional creatures
exceptionalcreatures.com
exceptionalcreatures.com
Until I read "why's (poignant) Guide to Ruby", from start to end, I completely fell in love with programming. Everything before was just getting to this point.
The documentation and community is what has drawn me into Ruby. The language and now very major ecosystem is why I still stay :)
Hello Ruby by Linda Luikas is one of the sweetest 'programming books' I've ever seen.
Theres probably a lot of documentation that could be aided by illustrations like this along the lines of analogy and metaphor. Aside from making the process of reading documentation more fun, it probably helps differentiate long and complex documentation that otherwise might blur together.
For a reference, I want something I can trust to give information relevant to my purpose, something that is complete and valid. Not a playful hidden advertisement, funneling me into a single paid solution. Maybe this is why I prefer python, even after working with rails for many years. As I said, I might be a bit dull.
15 years ago I would have agreed. Today, Python is a "gateway" to programming that is also the real thing.
It's like one of those old languages designed for beginners to learn coding... and then you can continue to use the same language for your entire professional career as a software engineer, to build just about any production-ready application.
Ruby is a beautiful language, but unless you are going to be working with Rails, it's not a very practical language to build something in. And I don't think telling a beginner "just learn Ruby for now, but once you're actually ready to write your first useful program, you're probably going to have to learn another language" is very motivating.
I'd say both are pretty bad at performance critical tasks or UI stuff where usually you would use neither of those.
And that's just what I can recall of the top of my head as someone whose primary language is not Python.
What? 99% of science has nothing to do with machine learning. Jupyter is used in a million different environments such as pure mathematics or computational chemistry where machine learning is almost completely absent.
> and you can't say with a straight face that python is a meaningful player in the Web application space, beyond its niche
According to the 2023 Stack Overflow Developer Survey[1], Django is more than twice as widely used as Ruby on Rails.
> According to the 2023 Stack Overflow Developer Survey[1], Django is more than twice as widely used as Ruby on Rails.
Even I'd consider SO surveys relevant, it'd still be a niche, just a bigger niche than rails.
For games, none of the big engines are python or ruby based and Micropython is more of a Python dialect to me with some partial compatibility, you can't just pip install what you want.
"Nobody" uses Python for 2D games. "Nobody" uses Ruby either, but there's Dragonruby (write once, deploy to Windows, Mac, Linux, Web Assembly, iOS, Android, Nintendo Switch, XBOX One, and PS4).
There's interop for many other programming languages, including several options for embedding Python code in Ruby (and the reverse). I've come across Ruby embedded more places than I've come across embedded Python (the number of companies I've come across both are in the single digits).
But ultimately it doesn't matter. If you pick jobs based on currently used languages rather than what you want to work on, you're painting yourself into a corner with either language.
However Python is a easy transition. I rarely struggle to do anything with it when I need it. Even Django wasn't to weird to grasp after years of rails.
IMO it's not to relevant which language you choose to learn in the beginning of your career. Whatever is more fun or works better for your interests.
Early on you should aim to get exposure to multiple languages, ideally at least some very different ones.
So I agree with whatever is more fun. Anything that makes you want to stick with learning is great. Then you can, and should, explore.
If you want something that'll be a marketable skill right away, maybe Python will be a shortcut in the short term, but a developer who knows only one language - whichever one - is eventually going to be at a disadvantage.
The most important skill is not any specific language, but learning how to think about software.
'If you want to build a ship, don't drum up people to collect wood or assign them tasks and work. Instead, teach them to long for the endless immensity of the sea.'
This resonates with how I feel about programming languages. Python might be more practical, but does it ignite a passion for coding like Ruby has historically done? I remember dabbling in Python, Perl, and JavaScript (ES5) back in high school, but it wasn't until I rediscovered programming through Ruby that I truly began to enjoy it.Nowadays, I might not default to Ruby for new projects, having moved on to OCaml and Elixir, among others. Yet, there's something about Ruby's community (its charm and gentleness,) that's missing in many others. This nurturing environment is invaluable for beginners. It's noteworthy how members of the Ruby community, like José Valim with Elixir, Yehuda Katz with Ember.js and Rust, and Chris McCord with Phoenix, have carried this spirit of playfulness and a deep care for developer experience into other communities they've joined.
For context: I worked with C, C#, some Python and now mostly work in Go.
There are plenty of things I'd like to be different about Ruby and the tooling, but with Ruby I feel like I'm crafting something that at least has the potential for elegance, whereas looking at Python code is like staring at a brutalist building that spews its innards all over its surface.
(and yes, I realise some people love brutalist buildings, and I can too, sometime, when particularly well done, and that's why I chose that example - it's possible to do amazing and elegant things in any language, even - as ugly as I personally find it - Python)
It's part of modern science/technology culture to indiscriminately hate the most widespread things.
Personally, I find Python simply amazing and delightful to work with. And I consider its syntax, especially semantic indentation which eliminates so much visual noise, to be the best among all languages that ever achieved widespread adoption.
This is evasive. How often did you see people describe Python that way before it became as widespread as it is now?
> And I consider its syntax, especially semantic indentation which eliminates so much visual noise, to be the best among all languages that ever achieved widespread adoption.
And for me it is why Python will never even make my top 10 preferred languages, and is a language I actively avoid when I have a chance, because I find it visually absolutely awful. I'd suspect (yes, it's pure speculation) you'll find about as many people who detest Python over that alone, as who find Python "delightful". Useful, sure, but finding people who describe Python as delightful is a rarity.
But as I said, some people find brutalist architecture to be amazing too, and that's fair enough.
Quite a lot back in the early 2.x era before the Rails hype first kicked in. It really was a breath of fresh air compared to VB, Perl, JS, early Java or PHP of the time. It had a concise elegant clarity and consistency missing in other mainstream languages back then. And it was a relatively unknown underdog.
eg relevant to HN, here is PG talking about Python 20yrs ago: https://paulgraham.com/pypar.html
I've spent the last decade in Ruby shops and not done much Python recently, but I still miss those early Python days. Ruby never gave me the same sense of happiness it gave others and there are still things I prefer about Python. But it is subjective and I couldn't objectively say Python is better than Ruby.
Things are very different now - it is a much larger language with a much longer history to trip over, pulled in multiple directions with conflicting expectations, and the user base has changed from that small passionate dedicated community to being the intro to coding blub language that Java or PHP used to be where the average skill level is much lower.
I think the major reason for cultural change is that there's fewer people learning programming for fun, and more people learning it either because it's mandatory or as a career path. In which case, the humour and culture that comes out of that is naturally going to be different. I think that's affected Python more than Ruby just because Python is more widely used, particularly by these newer developers. As a result, there's been less cultural shift in Ruby than in Python.
So I think in a sense, you've got the cart before the horse. Python has less of the twee humour now because it's more widely used by newer developers, who in turn are no longer treating programming as a hobby and instead as a career. That said, I can imagine if you want to teach the joy of programming as a hobby, Ruby might be a better choice. Although with that said, I feel like a lot of the hobbyist Python community has moved to things like Raspberry Pi and MicroPython, so maybe it's just a case of finding other hobbyists and doing whatever they're doing: the community is more important than the tool!
But most Ruby use is "corporate" as well - its use is dominated by Rails shops. The "joy of programming" aspect of Ruby is partially embedded even in corporate Rails use, but also outside of it. It may well have hampered Ruby growth, but it's also not something I think would disappear if Ruby use increased.
Go, for example, is aimed at people who love making programs.
1. significant whitespace was so hard to grasp. I was a beginner so I just needed to write awful code
2. Ruby was so "pure" from the OOP perspective that I had one thing less to think about: method calls start from object instances, period. Python has "exceptions" to this rule that made me confused (f.e. `len` in Python is a global function, while in Ruby is `array.length`)
3. I found Ruby matching more to English language
Later I found that Ruby has deeply obscure islands (metaprogramming mainly, but also exotic syntax coming from Perl), but I was already sold to the language
You mean something like Shopify, Stripe or Github? So switch to Python instead so you can be constrained by single-line lambdas and a runtime that performs almost exactly the same as Ruby?
Discussions about C devolve into a religious war about simplicity and portability vs safety and an inadequate standard library.
Discussions about C++ devolve into a religious war about memory safety, bloat, developer competency, UB, and more.
Discussions about Haskell devolve into a religious war about powerful type systems and language constructs vs performance concerns, development complexity, and "endofunctors, lol."
Discussions about JS devolve into a religious war about npm, web dev in general, "== vs === lol" and more.
Discussions about Rust... oh boy.
In my experience, most discussions of specific components of languages inevitably spill into these broad and neverending religious wars.
Discussions about Go devolve into a religious war about simplicity and portability vs "the creators of the language said its only for dum dums and it shows", "it took them 10+ years to get generics", and more.
Discussion about Zig devolve into a religious war about living in a universe where C exists and not wanting to write it versus "there's too many C-likes", "why isn't this Rust", and more.
Discussions about Erlang devolve into a religious war about standing up fault tolerant and scalable distributed systems, Joe was the nicest guy ever vs "you can do that in X all you have to do is Y".
Discussions about Elixir devolve into a religious war about Erlang and Ruby's love child, José Valim is the nicest guy ever versus "you can do that in X all you have to do is Y", "but what about types" and more.
Discussions about Clojure devolve into a religious war about people writing impressive programs in their spare time, "I actually get paid to write Clojure" versus "does anyone actually get paid to write Clojure".
Discussions about Elm devolve into a religious war about type safety and staying sane versus Richard Feldman lost his temper once, the 0.19 release and "everyone has Stockholm syndrome over there".
Discussions about V devolve into a religious war about "this is not a scam" versus "this is a scam".
Discussions about Nim generally don't, or the language creator is going off on D-forums / Twitter / X again.
You can see that in Go. It was a hugely hyped language, backed by Google, but without a lot of wishlist items that C++/Java/Python/Ruby/etc developers would have liked.
You can see that with Rust. There is the “rewrite everything in rust” crowd, which inspires anti-rust people to speak up.
I find it crazy how much criticism Rust, Go, Ruby, etc receive when Python has such glaring flaws. From the 2-to-3 migration, to package management. The consensus seems to be that’s just the cost of doing business.
By the way, I’m a Python developer. I don’t hate Ruby. But it seems like most Ruby fans love the elegance and consistency of its design, whereas that never resonated with me. E.g calling obj.length rather then len(obj) is surely more elegant. I never really cared though?
I guess I just find it interesting how some languages cons are excused while others aren’t. And how people can be drawn to some languages while others hate them.
Ruby gets a lot of criticism for embracing magic and indirection ("Ruby, the bad parts of Perl"). It has some good parts (no function colors, for example), but the ecosystem is the biggest problem by promoting magic. method_missing is not a good part of Ruby, it's a very bad part that you should only use if you know it's bad _and_ you know you still have to use it. I wish all tutorials would say this. "You can do this with Ruby, but don't, because your coworkers debugging an outage for an hour will hate you once they find out the bug is caused by method_missing".
Result was objects that shared no structure, no field
Unfortunately some people started following without full understanding. I wasn't at forefront of things back then, so I only noticed when the people who did know better started to writing about abuse of this technique.
Writing code without thinking will cut you either way.
Things like method missing are exactly the right solution for a certain set of problems. If used thoughtfully, they’re amazing. If used thoughtlessly, bloody mess. But this is true in every language.
Early in my career I made my own toy ActiveRecord implementation and it's full of define_method and was literally the first time in my life that programming felt like a real superpower.
I think it's the most enjoyable language I've used. With care and feeding it's amazing. I would absolutely not want to use it in a large company, that would be a walking nightmare.
Avoid mutating arguments.
Avoid monkeypatching.
...
Avoid needless metaprogramming.
Prefer public_send over send so as not to circumvent private protected visibility.
Write ruby -w safe code.
...
[0]: https://ruby-style-guide.shopify.dev/#generalIf we were chefs a knife would be your laptop, your editor, your cli tools. Not your programming language.
A better metaphor would be the lumber in a building or the soil in a garden. I don’t know what I’d call ruby in this metaphor, maybe “lightweight wood that splinters”…
That being said, the original "Sharp Knives" piece is talking about powerful language features and whether to ban them in your kitchen, so yes, it has plenty of effect on their coworkers. Because it's a shared decision to not ban sharp knives from the kitchen, but trust and educate, and realize that people who're doing harmful things can do so with dull knives too. It's about the techniques you allow in your codebase, it doesn't propose that ruby is one "knife".
And programming language features does not, generally, end up on the plate of the customer either. The fact that this site is written in a language that allows even more powerful meta programming than ruby is not bleeding through in the sense that we now have the tools of the language available to us. We haven't been served sharp knives. We've been served the consequences of the engineering that went into it, and the people doing that engineering had the opportunity to leverage or ignore the sharp knives of the language. That language being lisp, I'm pretty sure they had at it.
Point being: In Ruby, sharp knives are too accessible, come with no warning or even encouragement.
Yet contrary to actual sharp knives (or guns pointed at feet) the feedback loop is slow. When you shoot yourself in the foot, or cut your finger, you feel it right away and (hopefully) adjust before more accidents happen. With Ruby, a footgun is fired today. Or a sharp knife carelessly tossed in the bag yesterday. But you'll feel the pain in months or years only. And probably not even you, but the person who followed your follow up.
Sharp knives are cool. But they need education on their dangers and responsibilities.
They’re still better than nothing, though. Method-mossing and friends played a critical role in making a framework like Rails possible in Ruby. In contrast, languages like Python and JavaScript just aren’t quite expressive enough to do it. A lot of energy went into attempts over the years, too! At best, something like Sails could get 2/3 off the way there and offer significant advantages on another axis, like making websockets first class.
I think a lot of the metaprogramming abilities Python has are just used less often than in Ruby. Not because it is less expressive, but because it has a culture of simplicity whereas brevity and generality are more valued in Ruby (Rails) culture.
https://stackoverflow.com/questions/7079855/are-there-techni...
If we're talking about Rails at least, then meta-programming/magic/indirection, all that should be very rare in application code. It makes sense sometimes in more abstract libraries, where you have to handle flexible problems, but in application code it's really worthwhile to just be straightforward and verbose.
It creates code bases that seems to have a tendency to turn into sprawling messes. I appreciate that it has driven a lot of people to Ruby, and in that way it's an amazing and impressive success, but recruiters get it somewhat right for the wrong reason when they sometimes list Rails as a "language".
I'm very happy to use "magic" in Ruby, but it should be high-impact, low code, and contained. E.g. I'm very comfortable with the "magic" in my window manager that turns event classes received from the X11 binding into method call on a target class, so that MotionNotify turns into target.on_motion_notify(event) without me having to specify every event class. It's simple, small, and let me cut a lot of code.
A lot of non-Rubyists would hate it, though.
The irony, though, about your complaint is that Rails code is some of the most verbose Ruby code you'll find, because it's geared at making cookie cutter creation of sites easy, and so a lot of patterns involve an excessive separation into vast amounts of low-impact, verbose classes that do way too little (the obsession with some Rails devs of writing "service classes" for things that should just have been a single method, for example, drives me crazy - yes there are valid uses of service classes, no almost no uses of them in Rails apps are reasonable)
The main complaint about method_missing has always been the inefficiency. The class hierarchy is walked every single time and only then is method_missing called. The use of define_method is a pretty neat solution to that problem. The method that wasn't found gets defined and it doesn't rely on method_missing again. Like a cache.
Personally, I've never used method_missing. Might have missed opportunities to write clever code, but I'm super happy being boring and explicit.
Tangentially, I've only used meta programming twice. Both where the alternative was cumbersome, and it was unlikely to cause confusion.
Ruby gives some exotic tools but doesn't force you to use them if you prefer not to.
If the set of messages you need to handle dynamically is to only ever be small, define_method() is the better choice, but when it is not, I'll take careful use of method_missing over some monstrosity that ends up emulating the same machinery with lots of extra code any day.
If you struggle with debugging due to method_missing, consider reviewing how you debug code, as it wouldn't even make my top ten of debugging challenges in the Ruby code I've worked on in the last 17 years of daily Ruby use.
All the most heinous bugs I've had to deal with in my life were about magic in ruby. I've worked in 3 of the biggest rails codebases in the world, and in the end we had build checks to deny code with magic.
Software code should be optmised for reading and debugging, not looking nice for first time writes.
Ruby is "an offender" in this to you because you hate the pattern that untangles the huge unholy mess that less dynamic languages use instead. E.g. hacky workarounds like whole class hierarchies or (marginally better) maps from values you dispatch on to first order functions/closures
I have worked in over a dozen languages, and I've never seen a medium to large sized project where some form of dispatch mechanism hasn't been part of the codebase somewhere.
And I'll take the simplicity of dynamic dispatch over hand rolling verbose mappings any day.
> All the most heinous bugs I've had to deal with in my life were about magic in ruby. I've worked in 3 of the biggest rails codebases in the world, and in the end we had build checks to deny code with magic.
I have no like for Rails, it encourages a lot of awful shit, but I also find this really curious, because the backtraces will clearly indicate you've passed through method_missing, you can breakpoint requests and attach remote debuggers to in flight requests, and execute code in-context in those requests.
If that's too complex, sure, maybe a large Rails code base isn't right for you. I don't want to work on Rails codebases either, but because of Rails, not Ruby, nor because the dynamism makes it any harder to debug.
> Software code should be optmised for reading and debugging, not looking nice for first time writes.
I agree,and it's exactly why I love Ruby.
As a dynamic language, Ruby gives you a lot of tools to create fully expressive code. This is just one aspect of it that you can, but don't have to, use.
This argument isn't entirely true anymore. The Ruby ecosystem has mostly moved away from meta-programming, and embraced classical OOP. Rubyists now tend to avoid `method_missing` and `const_missing` when possible, and abandoned the craze of making everything a DSL. The most meta-programming that Rubyists still use on a regular basis is defining `self.included` on modules in order to inject other modules. Also, Rubyists have embraced API documentation, such as YARD, in order to document and communicate any "magic" that might exist or occur.