IRB type completion comes as a result of a chain of events which starts from the incredible work done by Kevin Newton (et al) to write a new canonical Ruby parser called Prism in C99 with no dependencies [1].
With Prism, you can then create tool suites like syntax_tree [2], which then leads Prettier formatters [3], a new Ruby LSP [4], which unlocks a new Ruby LSP VS Code extension [5], not to mention a laundry list of other gems like Rubocop and of course Ruby itself that will benefit from a faster and more maintainable Ruby parser.
It's a beautiful illustration of the power of questioning conventions, going back to first principles to uncover better solutions to previously solved problems, whose new solutions create new capabilities which unlocks the ability to solve new problems.
syntax_tree was actually created before Prism. Ruby LSP also adopted syntax_tree first, and then switched to Prism (then called YARP) when it was mature enough.
But indeed, the type completor would've been much harder to build and maintain if without Prism.
> In Ruby 3.1, IRB introduced the autocompletion feature. While it has proven to be a useful feature for many users, it also came with some issues that were hard to overlook <lists several>
Really appreciate the attention to detail. I know little of ruby's internals, so usability flaws like those mentioned are difficult to put into google and try to fix (some usability hiccups are not due to bugs but due to misconfigurations - i.e. something I've set up incorrectly). These little quality of life improvements make a world of difference when using IRB for hours to get stuff done. Thank you to all those that make ruby awesome!
Yea im confused. I use IRB all the time to test some one off stuff, and !reload. but im not editing in the IRB or docker container on the proxmox vm for locacl dev.
It’s cool to see code in an interpreted language being edited at the repl. Ruby’s style of building everything at runtime using the language itself has always felt delightfully consistent, but also very hard to reason about with static analysis — the usually tool for helping developers in their IDEa and LSP clients.
Far nicer to just execute the program and put a breakpoint at the cursor…
This feels like the only way my editor stands a chance of completing this to Sheep::Black. Is this how Ruby IDE support works (e.g. in the JetBrains product.)
No, you couldn't. If running the code is too dangerous, then so is running the unit test suite. You'd have to prove that it doesn't do anything observable, like accidentally deleting your home directory, or, if the code is actively malicious, uploading your SSH key somewhere. And if you can do that, you probably also have enough information to provide good completion without running the code.
You can use whichever editor you prefer from irb with an extension (might be builtin now? I mostly use pry, which respects $EDITOR) - the last thing I'd want would be an editor forced on me. The multi line input is for the really trivial stuff.
I love pry+byebug so much that I'm having a hard time wrapping my head around why I might want to replace them with this. I guess for a marginally more out-of-the-box and universally available tool, eh? I'll have to look into the extensibility aspects.
Pry and byebug paved the way in a lot of ways for this work, but they break in fundamental ways across a range of use cases, such as multithreading, multifiber, or quirk around exception handling. While these are all fixable, so we're the lack of standard quality tooling , which is quietly being addressed by irb and debug gems.
Byebug and pry are pretty much the first gems I add to any gemfile. But like the other comment said, they break in a few ways that this new irb seems not to.
One thing I can think of is multi line statements (on Byebug). Really annoying to test longer method chains. Would love a debugger that supports it out of the box, as the new irb seems to do.
Removing two external dependencies from your project is a nice win. I switched a while back. Get used to "binding.irb" and you'll thank yourself later.
I spent many hours (back in the 1.8 days) in a Ruby focused irc chat room with some guys, many who went on to found relatively interesting companies (hey Evan and Chris :) ). I was just a teen, Rails was huge, and _why was writing some of the most inspiring code of all time.
At the time, to inspect what you could do with an instance, I wrote `my_thing.methods.sort - Object.new.methods.sort` many a time. It's great to see features making IRB even better after all these years.
This is so cool. I have been trying to replace the default history lookup in irb with fzf but have not found a clear path to do so. Maybe the irb team can also make it easier to do this.
it works for me on linux, not sure about other OS's. Although I'm now noticing that the article linked in the original post says that Ruby has a pure Ruby replacement for readline: Reline. So I wonder if it will not work with more recent versions of Ruby that use Reline?
Same here. Worst case is wrapping Python, but more Python libraries than you might expect have Ruby translations that are at least in progress. Still some areas that needs love, though.
To Ruby’s credit, they foresaw what others bolted on years if not decades after.
Remember Python didn’t start with being fully object oriented, everything is not exactly an object, they bolted on the useful functional stuff later (like every language has now after a weird period of people crapping on FP for some reason) and to top it off bundler, and Ruby version manager again were just largely copied over to Python as pip and venv. I like both languages, and I say this after getting schooled a few times about great things I thought Python did that I was a few times rather embarrassingly shown to have just been Ruby ideas picked up by others.
I’ll give you the language looks a bit funny and I’m not saying it’s better or anything, I work in Ruby and am all too aware of the warts. Just trying to share what I’ve learned that they did well because it’s a good and thoughtful community.
> Remember Python didn’t start with being fully object oriented, everything is not exactly an object, they bolted on the useful functional stuff later (like every language has now after a weird period of people crapping on FP for some reason)
None of that is actually true, to the extent that it makes any sense (which it doesn't really). Python had a complete object system and first class functions pretty much from the first preview, and anonymous functions (lambda), map, filter, and reduce were added before 1.0 was cut. Which predates the first public preview of Ruby.
> to top it off bundler, and Ruby version manager again were just largely copied over to Python as pip and venv.
And that is complete nonsense, virtualenvs have nothing to do with rvm, and pip is in no way a copy of bundler (not that it's in any way exceptional, it's a package manager).
> I say this after getting schooled a few times about great things I thought Python did that I was a few times rather embarrassingly shown to have just been Ruby ideas picked up by others.
So after getting told you were spouting nonsense one way you went on to spout nonsense the other way?
I believe you that pip has no relation to bundler and venvs have no relation to rvm or rbenv because bundler and rbenv are so much more intuitive and useful.
Poetry gets very close through, but it took decades to get there and afaik it is still not viewed as an "official" part of the toolset.
Venv tries to do too much and manages to not be great at anything, which is a direct contributing factor to Python being worst in class by a wide margin when it comes to packaging and dev environments.
I have the exact opposite experience, bundler + rbenv are so much nicer to use than pip and venv. rbenv automatically loads the correct ruby version when I enter a project directory and bundler is just so much more capable and intuitive than pip.
I never really liked Python much personally, I think it sits at an uncomfortable spot where it's still too verbose compared to other dynamic languages but not performant enough compared to static languages.
If I cared more about the expressiveness and the speed of prototyping at the expense of everything else, I would rather use Ruby which has much more stuff built-in and I'd accept to pay the price of its runtime penalty.
But if I cared more about performance, I'll rather use a static language like Go or Rust.
If I have to pay the dynamic language performance & maintenance tax, it needs to be worth it and I need to get some big advantages in return, otherwise I'd just use Go.
The few places I need more performance, I just use FFI and contain the tiny bits needed outside of Ruby. I wrote my MSc on using statistical approached to improve ocr error rates, and 99.9% or so of the code was Ruby - I needed to translate a few dozens of lines of code to C e.g. a knn implementation after I'd proven it worked.
In 18 years of Ruby use, this has been typical. E.g. I've done large scale (tens of thousands of layers) map tiles rendering in Ruby, and only a tiny core of the final rasterisation code was worth rewriting even back then at a time when Ruby was far slower.
The opinion is blown out of proportion, but there is a hint of truth. Large python projects are indeed easier to follow simply because of type annotations and signatures. Of course a lot of projects don't follow type conventions and try to invent their own optional parameter syntax using dictionaries and keyword expansion syntax, so the problem still exists everywhere.
Ruby has RBS and sorbet to support using type annotations. They are each relatively new and aren’t as clean and well integrated as Python’s implementation, but it’s not as if type annotations in Ruby don’t exist.
It does exist but they are not embraced by the majority of the Ruby community.
Unless type annotations are treated like first class citizen in the language, it won't be good enough. My theory is that those in the community wanting static types went to Go or Rust.
Of course anything can be done with RBS, but I think it came wayyy too late. Python type system is already given time to evolve and survive in the wild.
A second point is IDE support. It is so hard to get started with ruby auto-format, code completion, ctrl-click to follow code and debug. Python is readily usable in pycharm community edition.
And also produces so much waste since almost no one writing python thinks at all about performance leading to some of the dumbest looking architectures i have seen to scale up to even a small amount of requests.
I wouldn’t be so harsh, as to call it gross, but I also much prefer Python, because Ruby reminds me of Perl. It feels clever, but not in a way that I expect to shorten its BNF. It still bugs me a bit, that ruby has pascals ‘end’, and Python uses whitespace, but it worked out in the real world.
Given just the syntax, I would always recommend Python as a first language to scientists in a lab, rather than ruby. The code just reads and writes itself better, without special characters.
But, I think it’s not fair to call Ruby gross, given some people love C++, php, bash, JavaScript… I’d take ruby over many languages, given a choice.
Syntax is such a minor detail, I don't know why people care about it so much (unless it's APL or something similarly exotic).
The much bigger elephant in the room is the semantics. My personal pet peeve is that Ruby, just like Perl or C, doesn't have any sort of file-based isolation. While importing something in Python normally doesn't mess up any namespace except for the stuff you've just imported, Ruby basically leaves this to programmers' and they create monstrosities where one require statement can do way too much magic to my liking. And while there are some libraries and frameworks that are closer to Python in spirit ("explicit is better than implicit"), Rails is something that really throws me off as most things just magically happen to work with some incantation that seemingly comes out of thin air.
This new autocomplete thing may be a real breakthrough for people who learn by getting their hands dirty and trying to write something, probing around the available methods and functions to find the appropriate one. If it can suggest what's possible/available, a lot of the magic may fade away and become proper, explainable hard science.
What "special characters" are you talking about in Ruby? My impression is that Ruby and Python are roughly equivalent in terms of non-alphanumeric characters used in syntax.
Some symbols I can think of that Ruby uses that python doesn’t:
$ for global vars
@ for instance vars
:: for namespace stuff
=> for map key, value separator
{||} for blocks
.. and … for ranges
%w for special array construction
: for symbols
? and - in method names
?: for ternary expressions
#{} for string interpolation
And python that Ruby doesn’t have:
:: for slices
@ for decorators
And for the symbols that they both share, subjectively, a lot of them are used for often in Ruby.
Ruby does have the block related stuff like the & argument and the single line block { }. But other than that I also think it's relatively similar to Python (which doesn't even support blocks anyway).
From my perspective (DevOps/SRE) Ruby is a horrible platform. It is heavy on resources, it is difficult to run (Unicorn is a pain), maintain, monitor, debug. Many Ruby projects has silently failed (Chef? Puppet?) and the biggest Ruby tool in DevOps world which is Gitlab is incredibly difficult to run on premise and struggles with a ton of issues that I believe are caused by the platform.
If I had a choice, I would never work on a ruby project.
As both a Ruby programmer and an DevOps/Infrastructure in the past, I have found Ruby to be a superlative programming environment but just as easy to program in badly as any other. I have never found it harder to run, monitor or debug than any other platform, certainly not harder than building and tuning a Java server platform. Really I think Ruby has been the biggest influence for more brilliant tools and practices in modern development than anything else, even if it doesn’t come close to the performance of a static language.
You're spot on. You can see its influence in a lot of tooling coming after, such as several package managers (from yarn to cargo), java collections syntax, go structural typing, python's gunicorn, JVMs invokedynamic (introduced for jruby originally), among others I can't remember from the top of my head. Several new languages were created, or benefit from the collaboration of ex-rubyists, from elixir to rust to node, which greatly influenced their approach to developer ergonomics. Even if the world would refuse to stop using ruby forever (which will never happen, why would it...), its influence would last for a long time, after which it'd be rediscovered again after the mandatory forgetfulness cycle.
Some great examples there, and look at how many frameworks are “$LANG on Rails”!
Rubyists introduced me to automated provisioning and deployment - Puppet, Chef, Capistrano - as well as concepts like test-driven-development and the genius of metaprogramming, but it’s common to hear javascripters waxing lyrical about TDD while slagging off Ruby.
Ruby is like 12-Bar Blues: people who love rock music don’t always like hearing blues. My favourite story is about seeing Earl Slick and Bernard Fowler performing Bowie, and they struck up a long bluesy intro which caused one of the two older fellas standing next to me at the bar to turn to me and say, “I really don’t like all this blues crap!” only for the “blues crap” to become The Jean Genie two seconds later.
Careful what threads you try and unravel as they may weave your own narrative…
From my perspective of devops, I've built large hybrid cloud deployments in Ruby (from scratch, including an orchestrator written in Ruby) and would again given the right requirements, as for tooling the ease of writing Ruby outweigh anything else, and for running it it is no different or more complicated than any other container workload. It's a bizarre objection.
Whether you write unreadable code or not is not a function of language. This is a lazy attempt at criticism. My preference for Ruby is in part because reading and understanding well written Ruby is a joy compared to every other of the dozens of languages I've used.
And since (un)readable code is not a function of language, you cannot state in your next sentence that reading well written Ruby is joy in comparison with other languages.
Of course I can. There is no contradiction there. You can write readable code in any language, even assembly, but that does not mean well written code in a language that is also particularly readable won't be more of a joy to read than well written code in a verbose or hard to read language.
> The first statement is provably false, empirically, as huge systems are overwhelmingly not written in dynamically typed languages.
Your conclusion is not supported by the claim you try to support it with.
> Ruby is not one of these languages.
You're free you think so, but you've not provided anything but unsupported conjecture and logically invalid reasoning to support your belief, so rather than convince me, you've provided an additional reason to question your judgement.
What do you mean by huge systems? Many of the largest web platforms were indeed built with dynamically types languages. And these days Javascript somehow ends up being used for almost everything you can think except an OS kernel.
Chef's problems "with ruby" were largely design problems. The whole structure of the run collection and the "two pass parsing" design made it so that users had to almost immediately fully understand how the ruby parser saw ruby code. That wasn't really ruby's fault and there could have been other ways to structure recipes and avoid smacking new users with ruby syntax quite so hard.
With Prism, you can then create tool suites like syntax_tree [2], which then leads Prettier formatters [3], a new Ruby LSP [4], which unlocks a new Ruby LSP VS Code extension [5], not to mention a laundry list of other gems like Rubocop and of course Ruby itself that will benefit from a faster and more maintainable Ruby parser.
It's a beautiful illustration of the power of questioning conventions, going back to first principles to uncover better solutions to previously solved problems, whose new solutions create new capabilities which unlocks the ability to solve new problems.
[1]: https://github.com/ruby/prism [2]: https://github.com/ruby-syntax-tree/syntax_tree [3]: https://github.com/prettier/plugin-ruby [4]: https://github.com/Shopify/ruby-lsp [5]: https://marketplace.visualstudio.com/items?itemName=Shopify....