So congratulation and thanks to Matz, and all the other Ruby contributors for creating and maintaining and growing and improving this amazing language that's still my favorite. 2.5 looks great, and I can't wait to see what's in store for the future.
Although I don't really think the language is anything special (i.e. it's a standard dynamic OO language), what really turns me off Ruby is this dogmatic, almost religious aspect of its community.
Take POODR - it's more or less the community bible. If it's not written in POODR - don't do it. If it is - do it that way or else. It's POODR's way or the highway.
According to more experienced Rubyists more than 80% of the Ruby community use Rails. Rails is so widely spread that its development even fundamentally affects Ruby's roadmap.
Now irregardless of what you think about POODR or OO or dynamic types or whatever, a homogenous echo chamber filled with people chanting the same things over and over again is not a good thing.
As a counter example, take Javascript. Yes, it has its warts; its equality table is a joke. Ruby is a better thought out and implemented language in almost every aspect (although I do like Javascript's minimalism better, but that's a matter of taste I guess.) However, Javascript's community is as diverse, vibrant and experiment-friendly as it gets - there are the OO diehards, but there's also React, fantasy-land, macros, monads. People are trying out new things constantly.
Now I know you have monads in Ruby too or flow-like gradual typing libraries or rewrites of Clojure's spec. But at least where I work (and I work with some very experienced Ruby people) those libraries and the ideas they embody would never ever be considered as serious alternatives for anything. POODR or else.
Guess I've been faking it for the past nine years... I mean, I did start a company that used Ruby/Rails as the primary platform. And I've worked the last six years in a shop that currently has a team of about 12 Ruby/Rails developers...
Don't get me wrong, Ruby's a tool in my toolbox; I use it like I would any other tool. I like solving problems. Most modern languages make it easy and fun to solve problems.
I don't like when it's easy to see where a language is encumbered by poor choices (I seem to have a diametrically opposed viewpoint of your opinion of the Javascript community; to me, the redundancy, low quality and churn of community libraries is one of Javascript's greater liabilities). But if it works for you, that's great.
Language Holy Wars are necessary for young, budding languages and young, budding programmers. Language Holy Wars help young communities draw others to their banner and young programmers define themselves. Unfortunately, having causes and "bad guys" is a big part of the underlying way we work as people.
But at some point, once a language's adoption has reached critical mass & once you've reached a point where you're comfortable with the underlying paradigms of programming, these Language Holy Wars get left behind for more interesting problems.
I mean, I definitely have opinions about what language I'd prefer to be working in and why, but at this point, I make my determination of technology based on the right tool for the job, not necessarily my opinion of any given language.
I have never seen any resistance to experiments or diversity in the space. There's a happy path, but there's plenty of room, and welcoming communities, outside of it.
(I like JavaScript, too, for much the same reasons you do.)
Sandi Metz would tell anyone espousing that the text written in POODR is to be taken at face value as gospel that they're completely wrong and completely missing the point. I've actually personally seen her correct this behavior at a conference and at a workshop and I've heard her say it many times in many places and mediums (podcasts, blogs, interviews).
Anyone who says "it's POODR or the highway" should be corrected, because they are very dangerous to any software engineering endeavor.
some comments here mention that they've been doing ruby for years and never even heard of poodr. i think that's less of a point.
it sounds more like you feel stifled at your current job. there's no right answer when it comes to a software stack and it doesn't sound like your coworkers are excited about the same things you are. it doesn't have to be that way! i hope you find a new consulting (or full time gig) that stimulates you intellectually. merry christmas and happy new year.
I've also never come across any particular dogma in the Ruby community -- there are established best practices for formatting code, but individual projects vary widely style and design decisions. Most Ruby codebases I've worked on come with a custom `.rubocop.yml`, and that's it.
Congrats and thanks to all the core devs! :-)
Ruby is a cluster of inelegant and over concise cludges in the name of expressivity. The fact that it was once most famous for one of the most inelegant hacks - monkey patching - as a core feature speaks to that.
So I totally understand that it’s quick, it’s expressive, and it’s easy to prototype in. Agreed. It’s lost a lot of it’s shine there now but it’s all still true.
But elegant? It’s concise, not elegant.
Just because you can write a monstrosity in Ruby doesn’t make the language itself inelegant.
Ruby, of the many languages I’ve used, has by far the highest potential for code being poetry. You can find solutions that are incredibly simple and understandable due to so much boilerplate being remove from the syntax. Likewise you can write code that’s impressively concise without being inscrutable — I’m continually astonished by how readable Ruby can be.
One exercise in particular sticks out in my mind. Many years back, I implemented the first few dozen Project Euler problems in Ruby. However, I imposed a limitation: each solution had to be under 72 characters (library inclusions are fine), a single logical line, and readable. The end result was surprising at how naturally it ended up working — the solutions ended up being little more than the high-level conceptual approach, translated literally to code. Solutions ended up looking like the following:
(2 ** 1000).digits.sum
(2..10_000).amicable_numbers.sum
1901.to_year.upto(2001.to_year - 1).select {|d| d.mday + d.wday == 1 }.count
Sure, these depended upon injecting new methods into core classes, but who cares? For this problem it led toward incredibly straightforward and readable solutions for these problems. If this were library code I wouldn’t dream of doing it this way, but for application code — why not?I have yet to see any other language with Ruby’s capacity for readable conciseness.
But for example, Ruby's method-based control flow allows for sophisticated ideas to be expressed in a way that's clear but doesn't demand undue attention. A while back I needed to implement a common structure in Python for basically "repeat this operation with increasing sleep times until it succeeds" in the context of a particular library. Every option I could come up with was fairly inelegant, either requiring more attention than it deserved or being excessively oblique or just reading like a neural networks trained on Python, and none of the senior Pythonistas at my work could come up with anything much better. But I could clearly picture how to do it in Ruby, and it wouldn't have had any of those problems there. The extra expressiveness allows it to express the idea elegantly.
It’s certainly problematic when used! But the feature itself is elegant and the opposite of a hack. Disallowing monkey patching requires extra conditions and rules, not less.
For the cases where you have a tight loop taking up 99% of the actual CPU time it is also relatively easy to hook in C or Rust or whatever. Also, sometimes you hit hardware performance limits regardless of the language you use. We have some streaming download servers written for 99% in Ruby using the libCurl bindings that and they easily manage to fill up the 5 Gbps pipe* per server that AWS gives us.
* You can get 20 Gbps for some instances, but only to other instances in the same group. The biggest to the 'outside' seems to be 5 Gbps.
Rails also uses minitest with fixtures by default, I migrated to it recently and I really like the simplicity.
allow_any_instance_of(Set).to receive(:member?).and_return(true)
<rest of test code>
Contrast this for example with testing IO monad code in Haskell, where the best practice is to define a new monad 'underneath' your original monad stack, rewrite all your functions signatures to have a type constraint (of your new MonadIO type) and then switch out functions for their mocked equivalent as required by the test. Rspec can do the same switching out on any object or class, without any code required outside the test code. (Although as far as "handle with care" goes, monkeypatching the 'send' method has to score pretty high)Because of its use in scripting on the JVM(e.g. glue code and Gradle builds), Apache Groovy files are usually stored in the file system as text. Each time they're run, they are "compiled" into JVM bytecode. Although you can get pre-compiled .class and .jar files for Groovy, it's not common for people to build large systems with it.
- Standard Gems 2.5.0 - Default Gems, Bundled Gems // by Jan Lelis, Idiosyncratic Ruby
- 10 New Features in Ruby 2.5 // by Junichi Ito, Ruby programmer @ SonicGarden.jp
- 10 More New Features in Ruby 2.5 // by Tom Lord, Software Developer from London
- Performance Improvements in Ruby 2.5 // by Jesus Castello, Ruby Guides
- yield_self in Ruby 2.5 // by Michał Łomnicki
- Improved stacktrace display in Ruby 2.5 // by Michał Łomnicki
- Ruby 2.5 Series // by Amit Choudhary, Mohit Natoo et al @ BigBinary
http://engineering.appfolio.com/appfolio-engineering/2015/11...
About 5-10% performance improvement by removing all
trace instructions from overall bytecode (instruction
sequences). The trace instruction was added to support
the TracePoint. However, in most cases, TracePoint is
not used and trace instructions are pure overhead.
Instead, now we use a dynamic instrumentation technique.
See [Feature #14104] for more details.Ruby is still one of the most productive languages out there. I just love it. It gives me great joy that 10 years ago I chose Ruby to be the language for my future.
My wish this coming year is to be able to contribute more to the Ruby ecosystem.
Btw I’ve also built something using MRuby this year. The whole ecosystem is just great.
https://bugs.ruby-lang.org/issues/9569
Now to update the "how to generate secure random numbers in various programmming languages" documentation.
e.g.
class FooBar < Foo
prepend_before_filter only: [:create, :destroy] {
request.env["hello.skip_timeout"] = true }
end
was valid in ruby 2.4 but invalid now in 2.5Ruby is a joy to use.
e.backtrace.first lines to e.backtrace.last
Or maybe my favorite which is still good
puts “#{e.message} #{e.backtrace.join(“\n”)}”
Cheers to Matz and all the Ruby contributors :)
This is something I find to be using quite a lot, great to see this.
google-protobuf-3.5.0-universal-darwin requires ruby version < 2.5, >= 2.0, which is incompatible with the current version, ruby 2.5.0p0
[update]
looks like this is resolved by forcing bundler to compile instead of grabbing the precompiled versions.
I worked for a company a few years ago that made security software, with Ruby as a primary language, and this caused no end of frustration...
I forgot where the issue came from (I think it was some issue with bundler or ruby gems), but can I install 2.5 without breaking my set up?
In my daily work (Clojure) I can use different concurrency and typing models than Clojure originally envisioned, via core.async, clojure.spec. This is not some fairy tale or toy/PLT project.
How many languages can fundamentally change themselves without breaking things or getting awkward?
I used said chance, but I try not to disconnect too much from the ruby world as it's such a nice/productive ecosystem.
You never know when your Ruby skills can save the day again!