Ruby is a [[Ruby License]]/[[BSD-2]] dual-licensed programming language written in [[3. Reference/Software/Programming Languages/C|C]].
- [Website](https://www.ruby-lang.org/en/)
- [Source](https://git.ruby-lang.org/ruby.git)
- [Documentation](https://docs.ruby-lang.org/en/)
- [3rd Party Core API Documentation](https://rubyapi.org) (USE THIS! can be installed and run locally)
- [3rd Party Library Documentation](https://rubydoc.info/gems)
> A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.
\- official website
# Notability
I started using Ruby in 2006 and it is probably the single language I have written the most code in.
There are a lot of things I like about it, but even back in the early days there were things that I wished were done better. In the last several years I've felt like a lot of features were added haphazardly and there were design decisions that solidly relegated it to the background so it is fading in popularity with many of the biggest Rubyists having moved to other languages.
Interesting to me because there's also been an enormous amount of optimization under the hood and so there are a lot of things to learn about data structure and algorithms that work across a broad range of uses cases.
# Philosophy
The core team is terrified of making any breaking changes ever - partially with a reasonable justification of the [[Python]] 2 vs 3 fiasco. But this stops them from making much needed improvements to the language and hamstringing what would be major new features to maintain backwards compatibility.
And yet they often have broken backward compatibility, introduced half-baked experimental features, and created bizarre bugs in point releases many *many* times in the time that I have used the language.
There was no real test suite for Ruby for most of its lifetime - the core team didn't want one - so the only person who was crazy enough to build one anyway was also kind of a massive jerk.
Ruby has had a community of people that always had a very different vibe than any other programming language. A big influence on that was [[_why the lucky stiff]], who was also my introduction to the language via comedy and cartoon foxes. Few programming languages ever get such a beautiful, fun, and effective introduction.
Its core functionality is so intuitive that for the first several months I kept trying to make things harder than they needed to be because I refused to believe that a programming language would make things easy on me ever.
The documentation however has always been weak, although it has gotten a lot better in recent years, it is still pretty common that I have to crack open the source code to figure out what the hell is going on in there.
# OS Support
- Linux
- Haiku
- Mac
- Windows
# Features
My god its full of objects. But like in a good way for once. Everything behaves like an object and so everything can be treated like an object and this very nearly always works like you expect.
- Single inheritance with [[Ruby - Classes|classes]], multiple inheritance with [[Ruby - Modules|mixins]]
- Some [[Ruby - Refinements|subject-oriented]] features
- Some very specific [[Ruby - Pattern Matching|pattern matching]] features
# Tips
## Implementation
- [[Ruby - Tail Call Optimization]]
- [[Ruby - Implementation Tricks]]
## Handling Invalid/Unexpected Returns and Breaks in Blocks
There's no good way to do this unfortunately. And if either of those are encountered by `main` the application immediately exits! There are really only two things you can do to stop this.
You can disassemble the block's bytecode and identify the `return` or `break` instructions and then throw an error. This sounds insane, but this is the safest route.
```ruby
if RubyVM::InstructionSequence.disasm(block) =~ /^\d+ throw +1$/
raise LocalJumpError
end
```
The second option is to pass the block into `define_method` (or similar) and this will reset the binding of the block to the object it is defined on, preventing the program from exiting unexpectedly.
```ruby
o = Object.new
o.define_singleton_method :block_method, &block
o.block_method
```
This of courses loses all of your local scope, so you will need to capture and rebuild it manually if desired.
It's one of the few times I think to myself, wow [[blacklight]] did it better.
# References
- https://stackoverflow.com/questions/41100983/how-to-prevent-problems-with-return-from-block-when-using-ruby-yield
- https://jpcamara.com/2024/12/01/speeding-up-ruby.html