Settings

Theme

Ruby 2.5.0 Released

ruby-lang.org

431 points by phereford 8 years ago · 112 comments

Reader

skywhopper 8 years ago

When I discovered Ruby 12 years ago, it was an amazing moment. All the features I loved from my previous favorite languages Perl, Smalltalk, and Scheme in one place, but with a much more reasonable syntax, a far more robust standard library, a complete and dead-simple packaging system, and a practical and portable runtime. The fact that it still feels magical, fun, practical, and pragmatic all at the same time while progressing and improving step by step each release after all these years is a truly amazing feat, especially when you compare it to its peers.

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.

  • pka 8 years ago

    I started a new contracting gig a couple of months ago, in Ruby. I had used it briefly years before in another project, but it was so long ago that I had to learn it again basically from scratch.

    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.

    • tres 8 years ago

      Huh... didn't even know what POODR was...

      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.

      • pka 8 years ago

        (To you and everybody else)

        Point taken - apparently I mistook the particular echo chamber I happen to be in at that moment for a more general symptom. Glad to hear!

        • tres 8 years ago

          Sorry, I think I got a bit sidetracked in my response.

          I do hope that your current situation gets better or that you find somewhere that isn't so preoccupied with navel gazing.

      • andrei_says_ 8 years ago

        You may enjoy Practical Object Oriented Design with Ruby by Sandi Metz. Speaks about OO software design in very clear and easy to grasp way.

        I often share it with non-ruby devs because it’s about design much more than it is about ruby.

        Here are a couple of talks by the author which examplify her style of thinking and approaching problems.

        https://m.youtube.com/watch?v=29MAL8pJImQ

        https://m.youtube.com/watch?v=8bZh5LMaSmE

      • semperdark 8 years ago

        It's not just you. I've been running a company on Rails for four years - never heard of that book.

        • inopinatus 8 years ago

          As a Ruby ops programmer who came to Rails via Chef I had no exposure to Sandi Metz or any of the other Ruby OO thinkers. However, several years later, now that I have read and integrated the ideas in POODR to my work, I highly recommend it.

          Besides Sandi Metz, another Rubyist that I rate highly for delivering clear ideas about design is Avdi Grimm. His RubyTapas series quite radically changed my approach to building applications in Ruby.

          Observe that programming in Rails doesn't intrinsically require an OO mindset. But when I reached the limits of the framework, knowing a thing or two about building rich OO domain models served me very well and helped avoid anti-patterns.

    • eropple 8 years ago

      As a counterpoint, I have been writing Ruby as a primary language for about five years, both as an employee and a consultant. I am consistently solicited for advice on both code and architecture in Ruby by colleagues to positive results (and I do the same, don't get me wrong--that's how collegiate relationships should work). And, yet, I had to google what POODR was. I've also never used Rails; on this Christmas morning I'm noodling on a Grape API that uses grape-swagger for API documentation.

      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.)

    • heartbreak 8 years ago

      I'll pile on here with another counter data point to say that having written Ruby (both Rails and otherwise) for 7 years, and having read POODR, I do not understand where you're getting this dogma idea from. I have yet to experience a single instance of "It's POODR's way or the highway."

    • scruple 8 years ago

      > 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.

      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.

    • wasd 8 years ago

      hey pka,

      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.

    • woodruffw 8 years ago

      I've been writing Ruby for 4 years, and I had never heard of POODR before.

      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.

    • izietto 8 years ago

      Ruby & Rails developer since 1.8/2.2, never heard about POODR

    • rubyfan 8 years ago

      What is POODR?

      • heartbreak 8 years ago

        Practical Object-Oriented Design in Ruby by Sandi Metz.

        http://www.poodr.com/

        • qume 8 years ago

          Thanks. Rubiest here for a decade and hadn't heard of it.

          • rubyfan 8 years ago

            Same. I’ve seen Sandi speak and had a beer with her at Goruco like 10 years ago. Great speaker to be sure.

            I’ve never encountered anyone as passionate as @pka suggests. Perhaps POODR is popular where they work but it’s far from universal amongst rubyists.

nileshtrivedi 8 years ago

Ruby may not be the cool thing in town it once was, but it remains my preferred language for prototyping ideas - purely because of its elegance and expressivity. It truly delivers on its fundamental goal of "developer happiness". A lot of ideas from Ruby have gone to other languages (CoffeeScript, Elixir) and many web frameworks are modelled after Rails.

Congrats and thanks to all the core devs! :-)

  • abritinthebay 8 years ago

    See, expressive I totally get. Absolutely. But elegance? Don’t understand that one.

    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.

    • stouset 8 years ago

      Disagree 1000%.

      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.

      • AaronFriel 8 years ago

        Are you familiar with Rust, Haskell, C# or JavaScript?

        All of these allow creating new extension methods of existing types, albeit by three different methods.

        I'm assuming that your "2001.to_year - 1" is "the date time for 2001 minus 1 day"

        rust (traits)

            (pow::<BigInt>(2u8, 1000).digits().sum()
            (2..10_000).amicable_numbers().sum()
            1901.to_year().upto(2001.to_year() - 1.to_day()).days().iter().filter(|d| d.mday + d.wday == 1).count()
        
        
        Haskell (type classes)

            sum . digits $ 2 ^ 1000
            sum $ amicable_numbers [2..10000]
            count $ filter (\d -> mday d + wday d == 1) [year 1901 .. year 2000 - day 1]
        
        
        C# (extension methods)

            BigInteger.Pow(2, 1000).digits().sum()
            Enumerable.range(2,10000).amicable_numbers().sum()
            1901.ToYear().UpTo(2001.ToYear() - 1.ToDay()).Days().Where(d => d.mday + d.wday == 1).Count()
        
        
        JavaScript (changing prototypes)

            bigInt(2).pow(1000).digits().sum()
            _.range(2, 10000).amicable_numbers().sum()
            1901.to_year().upto(2001.to_year().minus(1)).days().filter(d => d.mday + d.wday === 1).length()
        • stouset 8 years ago

          Yes, I am familiar with all of them. :) Rust most of all, and that's another language I'm extremely happy with. The others to lesser extents, and Javascript is the only one of them where I'd say I dislike the language.

      • dmitriid 8 years ago

        > Sure, these depended upon injecting new methods into core classes, but who cares?

        I, as a developer reading your code 6 months later, care.

        When something fails, it's nearly impossible which of the magic methods were injected by which magic library.

        • nfm 8 years ago

          Not really. It's hard for your editor to do this statically, but there's heaps of good tooling for finding the method source and docs dynamically.

            pry> show-source SomeClass.class_method
            pry> show-source AnotherClass#instance_method
            # List an arbitrary object's class methods, instance methods, methods mixed in by included modules
            pry> cd some_object
            pry> ls
          
          The runtime knows how to execute your program (it's not random) so everything you want to know is available.
          • JohnBooty 8 years ago

            Been doing Ruby full-time for 3+ years, bunch of experience before that.

                there's heaps of good tooling for finding the 
                method source and docs dynamically
            
            I know, but this is a huge problem with a lot of code I see in the wild because this stuff is (ab)used so widely in Ruby-land.

            If I have to run code just to see where `Foo.bar` is defined, that makes things... about an order of magnitude harder to understand. I mean, that's really tough thing to do in anything but a trivial codebase.

            This is nearly 100% the fault of developers, not the language itself, but I would suspect that most Ruby developers spend a significant amount of time dealing with things like this because it's how the ecosystem rolls.

          • dmitriid 8 years ago

            You realise you just validated my point, right? :)

            • stouset 8 years ago

              I'm not sure you did.

              People who don't use Ruby seem to think this is a huge thing that you run into constantly. It's not. People are for the most part pretty responsible with these things.

        • inopinatus 8 years ago

          It’s very far from impossible. It is trivial to programmatically determine where a method was defined using Method#source_location.

          Determining which method responds to which message is only possible in an instantiated runtime, but that’s true for any late-binding programming environment. Complaining about it tells us more about the complainer than about the language.

        • nicoburns 8 years ago

          Rust's way of doing this is nice. It allows you to extend core types (e.g. add methods to integers), but in order to use the added methods you import the trait that adds them in the file you want to use them in (so you can always have a good idea of where they've come from)

        • stouset 8 years ago

          It's almost as if you didn't even bother reading the sentence immediately following.

          If you're writing a library doing things like this is a bad idea (except in very limited circumstances). And to what seems to be every non-Rubyist's surprise, virtually no libraries in practice actually do this sort of thing so there are never problems in practice.

          The times I do this sort of thing in my own application code, I put the methods in a module and have a hook that raises an exception if the methods already exist when the module is included. This is the best of both worlds: I can add features that don't exist, but am informed immediately when my app launches if such a method has already been defined.

    • chc 8 years ago

      I think there's a lot about its expressiveness that's elegant. You can't pick one inelegant practice and define the entire language by that — nothing would pass that test.

      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.

      • nerdponx 8 years ago

        What would the elegant Ruby version look like, and what was inelegant about the Python version?

        In Python I imagine you could just do something like this:

            from time import sleep
        
            sleep_increment = 1
            sleep_time = 0
            success = False
            while not success:
                sleep(sleep_time)
                success = try_thing()
                sleep_time += sleep_increment
        • stouset 8 years ago

              def backoff(wait = 5, exponent: 1.5)
                yield
              rescue BackoffError
                sleep(wait)
                wait = wait ** exponent
                retry
              end
          
              backoff { connect_to_a_thing }
          
          This is trivially composable with any other control flow you might want to write in Ruby.

          Personally I find the Python approach inelegant. Can it be composed? Why am I having to work with low-level looping constructs instead of higher level control flow constructs that map more closely to the task I’m actually trying to accomplish?

          Same thing goes for any non-functional looping at this point. Why am I having to care about loop indices, incrementing counters, creating result arrays and inserting items into them, etc.? It’s (almost) 2018 and people are still writing low-level looping logic for the n-billionth time. Worse, people have to read it and parse it for the n-trillionth time to figure out which looping idiom is being used, instead of being able to see at a glance that something is being mapped, selected from, reduced, etc.

          • masklinn 8 years ago

            Nothing precludes a similar approach in Python:

                def backoff(wait=5, exponent=1.5):
                    while True:
                        yield
                        sleep(wait)
                        wait = wait ** exponent
            
                for backoff():
                    connect_to_a_thing()
            
            Here's the question: do you need exponential backoff in more than one place? Because if you don't, bundling all of that doesn't buy you anything and the original works just fine.

            > This is trivially composable with any other control flow you might want to write in Ruby.

            And it is actually trivially composable with other Python control flow, it's just a backoff iterator, you can drive it however you want, or compose it with other iterators (e.g. enumerate() to know which instance you're on, islice to stop after a certain number of tries, …)

            • stouset 8 years ago

              Your solution is much cleaner to me, except (not really knowing Python) it looks like it might have a bug, in that the `while True` will never terminate.

              • masklinn 8 years ago

                > the `while True` will never terminate

                The iterator is infinite on purpose (it has no reason to be finite).

                You'd terminate it from outside, either when the operation succeeds, so the example loop should more properly be something along the lines of:

                    for _ in backoff():
                        try:
                            c = connect_to_a_thing()
                            break
                        except ConnectionError:
                            pass # retry
                
                or you'd use composition to e.g. stop after a set number of tries:

                    for _ in itertools.islice(backoff(), 5):
                        # do stuff
                
                most likely a combination of both.
              • creatornator 8 years ago

                I think you can break the for loop after the function call and it'll end after the wait is successful. Bit of a hack though

          • nerdponx 8 years ago

            It looks like the Ruby-specific elements here are (1) the 'retry' statement, and (2) the ability to yield a block twice (Python's equivalent `with` syntax explicitly prohibits re-yielding a block).

            (1) might just be a matter of taste -- that 'retry', to me, makes me now have to step back and think "oh, I'm retrying something now? what exactly is being retried here?" Having it all wrapped up in a 'while' loop makes the intent explicit right from the get-go.

            (2) I agree is nice. It would be great if you could do this:

                with backoff():
                    connect_to_a_thing()
            
            but you're not allowed to 'yield' twice inside a context manager. However you can get damn close (and fully composable) by wrapping the connection logic and the retry logic in functions:

                def connect_to_a_thing(url, access_token):
                    ...
            
                def backoff(connector, wait=5, exponent=1.5, *args, **kwargs):
                    success = False
                    while not success:
                        try:
                            connector(*args, **kwargs)
                        except BackoffError:
                            sleep(wait)
                            wait = wait ** exponent
                        else:
                            success = True
            
                backoff(connect_to_a_thing, url, access_token)
            
            Or you could be even more explicit with recursion:

                def backoff(connector, wait=5, exponent=1.5, *args, **kwargs):
                    try:
                        connector(*args, **kwargs)
                    except BackoffError:
                        sleep(wait)
                        backoff(connector, wait ** exponent, exponent, *args, **kwargs)
            
            As for your point about loop indices, Python generally has wonderful support for not worrying about loop indices and counters. I'm also not sure how that applies in this case; you still need to increment the value of 'wait'. Then again...

                def exponentiate_forever(value, exponent):
                    while True:
                        yield value
                        value = value ** exponent
            
                def backoff(connector, wait=5, exponent=1.5, *args, **kwargs):
                    for wait in exponentiate_forever(wait, exponent):
                        try:
                            connector(*args, **kwargs)
                        except BackoffError:
                            sleep(wait)
                        else:
                            break
            
            But please don't do that.
    • chrisseaton 8 years ago

      I don’t think you can call monkey patching inelegant or a hack. Monkey patching is the absence of extra rules - not allowing a method to be defined more than once - and the prescence of consistency - all methods can be redefined.

      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.

    • ouid 8 years ago

      Arguing that something isn't elegant is a lost cause.

    • nerdponx 8 years ago

      What's an example of one of those kludges? "Ruby concise" at least looks elegant, whereas, say, "Perl concise" is hideous.

      • stouset 8 years ago

        I’m continually impressed by how understandable golfed Ruby tends to be, especially when compared to Perl. Golfed Perl is completely inscrutable, whereas golfed Ruby is often times no less understandable than a longer version.

      • abritinthebay 8 years ago

        I disagree it even looks elegant. Short? Yes. Better than Perl? Sure, but even Perl fans wouldn’t call it a pretty language.

WJW 8 years ago

I started using Ruby only in April this year due to starting at a new job. Having used and/or dabbled in C, Java, Python and Haskell before (amongst others), I find it super interesting to see how Ruby manages to take some interesting parts from each and manages to integrate it into a very pleasant programming experience. Also the rspec testing library is nothing short of magic, none of the compiled languages have anything that even comes close IMO.

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.

  • grover_hartmann 8 years ago

    While rspec is indeed nice, I don't get why most projects don't use minitest more. Minitest ships with the Ruby standard library and I much prefer the assert syntax over the rspec DSL.

    Rails also uses minitest with fixtures by default, I migrated to it recently and I really like the simplicity.

    • lloeki 8 years ago

      minitest also provides a spec-style DSL. Rspec is a hog, minitest is much, much cleaner and leaner, even if you use the DSL.

  • fred123 8 years ago

    I'd be very interested to know what you mean by "nothing short of magic". I've had a quick look at the rspec documentation and as a Python dev this looks very similar to what's in the Python standard library. Would that be considered magic as well or does rspec have some cool features that I have missed?

    • WJW 8 years ago

      Note how I said compiled languages, I expect Python to have some very similar capabilities. :) But as an example, take the cleanness of the following mock:

        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)
    • chrisseaton 8 years ago

      rspec’s internal DSL is based on Ruby’s multi-line anonymous functions. I don’t know how you achieve a similar design in Python where you don’t have those in the same way. How do you write the equivalent of ‘it ‘does something’ do ... end’ in Python syntax?

  • 0x445442 8 years ago

    Not too familiar with Rspec but I know Groovy (a compiled language) has testing frameworks like Spock that I believe are based on Rspec.

    • vorg 8 years ago

      > Groovy (a compiled language)

      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.

  • taf2 8 years ago

    Cool which libcurl bindings are you using?

    • WJW 8 years ago

      Patron, from here: https://github.com/toland/patron. We use it in combination with our (open source) FastSend gem to keep the streamed data away from the Ruby garbage collector, since it gets a bit emotional if it has to clear out hundreds of MBs every second. If you're interested why we chose this architecture instead of just redirecting to S3, our lead engineer gave a talk about the reasoning behind this structure. You can find the slides at https://speakerdeck.com/julik/streaming-large-files-with-rub....

      • raggi 8 years ago

        You can fill GB/s with net/http. You could do so easily with 1.9. The GC shouldn't be a problem unless your object graph is very complicated.

geraldbauer 8 years ago

FYI: I've collected articles / blog posts about what's new in Ruby 2.5 over at the Ruby Advent Calendar [1]. The list so far includes:

- 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

[1]: https://planetruby.github.io/advent2017

greysteil 8 years ago

Nice to see the 3x3 work continuing to go well with that 5-10% speed up. For anyone who hasn’t seen it, Ruby declared a target for Ruby 3.0 to be 3x faster than 2.0.

http://engineering.appfolio.com/appfolio-engineering/2015/11...

  • diminish 8 years ago

    What particular speed improvements do we expect from 2.5.0 release? String interpolation speedup?

    • greysteil 8 years ago

      ERB generation should be a lot faster, which will be a boon for a lot of Rails apps, and according to the release notes there's a 5-10% performance improvement overall from removing all trace instructions from bytecode.

    • WJW 8 years ago

      In addition to the ERB generation and removing all the tracepoints mentioned in the sister comment, there is also a change in the hash function used for Hashmaps. The new one needs roughly half the hashing iterations so it should slightly speed up any application that uses hashtables. (aka pretty much every ruby app)

    • JohnBooty 8 years ago

      Among others, from the linked article:

          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.
elliotlarson 8 years ago

Oh, it looks like Bundler didn't make it into the standard library for the 2.5 release. The commit to bring it in was reverted just before the release, with very little explanation. I mean, it's not like `gem install bundler` is that hard to do, but I'd be curious to hear why.

  • ksec 8 years ago

    Same thoughts here, I thought that was the important step to gemify everything in 2.6. Are they reverting course?

artellectual 8 years ago

Was waiting for this!! Super happy about this. I’ve come to expect this every year now at this time.

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.

  • eropple 8 years ago

    I've really wanted to find a good use for MRuby (probably to noodle around with game development, as an embedded language) but figuring out where to start is really hard. Any tips?

CiPHPerCoder 8 years ago

Ruby's SecureRandom is finally sane to use? It's like Christmas or something!

https://bugs.ruby-lang.org/issues/9569

Now to update the "how to generate secure random numbers in various programmming languages" documentation.

taf2 8 years ago

Anyone else noticing syntax ruby parser regressions?

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.5
iovrthoughtthis 8 years ago

rescue on do blocks!!! Wooooo. Merry Christmas!

Ruby is a joy to use.

  • Lockyy 8 years ago

    Can’t beat reversing the backtrace output for making Ruby even more enjoyable. Slogging up through a huge pile of calls was one of the few things that drove me mad.

    • taf2 8 years ago

      Just need to rework all these

      e.backtrace.first lines to e.backtrace.last

      Or maybe my favorite which is still good

      puts “#{e.message} #{e.backtrace.join(“\n”)}”

      • sampriti 8 years ago

        That code will still work, they are using the experimental feature only when the backtrace is printed to a tty.

  • burlesona 8 years ago

    Best thing to ever happen to Sinatra and the many block-oriented frameworks. Been looking forward to this one all year :D

raitom 8 years ago

Every year it's the Christmas gift I wait the most!

burlesona 8 years ago

There's no such thing as a perfect language, but Ruby is a very nice one, and the community is just such fun. The tradition of major version releases on Christmas Day each year is one of my favorite things!

Cheers to Matz and all the Ruby contributors :)

hit8run 8 years ago

I absolutely love ruby and its community :) My software goals for next year: - Start a new platform built on Ruby/Rails. - Contribute to the ruby eco-system. - Enjoy it.

drchiu 8 years ago

Love Ruby. Back a few years ago before I learned to program properly, I found a lot of the syntax of various languages to be hard to understand. I was not trained as a computer science major, mind you. Nonetheless, the syntax of the Ruby language made things easy enough for me to digest. Heck, even ended up starting a Ruby based software company won’t employees — something I couldn’t have imagined doing even a decade ago.

jph 8 years ago

Test Driven Development (TDD) gets a huge improvement with the new coverage capabilities for methods and branches. Thanks Ruby team!

  • ajmurmann 8 years ago

    I'm surprised by this comment. Having done TDD for many years now I've only ever felt the need for coverage tools on code that wasn't initially TDDed. If you do proper TDD your coverage is always pretty damn close to 100% and you are already well aware of where it isn't because you struggled TDDing in the first place.

    • allcentury 8 years ago

      That's true until you decide to delete tests/code that is no longer in use. Then it becomes much more difficult to track down dead code paths

drish 8 years ago

> Mutex is rewritten to be smaller and faster. [Feature #13517]

This is something I find to be using quite a lot, great to see this.

taf2 8 years ago

looks like we have some gem authors that need to update their stuff...

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.

nazgob 8 years ago

Many thanks to all who contributed!

onetwotree 8 years ago

Hey they finally fixed the issue with SecureRandom using OpenSSL instead of the OS CSPRNG implementation!

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...

rajangdavis 8 years ago

I had installed Ruby on a Windows 10 machine a few weeks back and had some issues setting up Ruby 2.4.*.

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?

knodi 8 years ago

Jebus!! this is about Ruby 2.5.0 release not about why you think Ruby sucks.

artsky 8 years ago

Awesome! I'm excited about the new yield_self method, and the general functional programming direction that Ruby is moving in.

igravious 8 years ago

Thank you Matz & co. <3

pankajdoharey 8 years ago

i loved ruby and i still do but my focus has now shifted to scheme/clojure and lisp family dialects like racket, and i don’t see a reason to return or move to anything else it feels like my search is over.

  • eropple 8 years ago

    If your "search is over", you're doing it wrong. Something sucks about everything you are using, no matter what it is. There is a better thing, even if you must make it.

    • vemv 8 years ago

      Would agree with your view, but Lisps are arbitrarily powerful by the means of macros and interop.

      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?

      • eropple 8 years ago

        Lisps are arbitrarily powerful, yes, sure. Once I too was a Lisp head, I am familiar with the advocacy.

        They also read awfully even with an editor designed for them. They aren't human-first languages. S-expressions are easy for a computer, they are hard for a human. So, yeah, that can be improved, too. "But you can do it with macros"--other people won't, and so you are thus devolved to the minimum set everyone can agree upon, and it's gonna be awful.

        And so there is room to grow outside of one's parentheses, too.

        • flavio81 8 years ago

          >They aren't human-first languages. S-expressions are easy for a computer, they are hard for a human.

          I've used Python, C, C++, C#, Java and Pascal extensively. I can safely say Common Lisp allows you to write the most readable code of all languages i've used, and i'd expect this to be the same for most other lisps.

          Since they are hugely flexible, they allow you to write code in such a way that the problem and solution are expressed in the most explicit and straightforward way.

        • vemv 8 years ago

          Threading macros (-> / ->>) can greatly improve readability, putting lisps on par with Ruby (which I appreciate much).

          Best of all, emacs/Cursive lets you trivially transform a sexpr into a threading form, and back. So one doesn't even have to do much effort for refactoring nested (a(b(c(d calls.

          • eropple 8 years ago

            I totally get that--what I'm saying is that, much like something like C++, you can only practically use the subset everybody you have to work with will agree is acceptable. Threading macros, IMO, help but don't really solve the readability problem, and it's still a far sight from Ruby, but it's a good step. But you have to get Bill the chin-stroking graybeard down the hall to use them when they're "not how he uses Lisp." Contrast this to a language with more guardrails--the equivalent of that threading macro in Ruby (or in Scala, or in F#) is just...The Way You Do It, it's the standard of the tools involved.

            You're transforming a linguistic readability issue into a cultural problem of agreement and that's a waaaay harder problem to solve, IMO. Lisps are cool. But every problem raised to "cultural problem" is so much harder to solve. (When was the last time you saw an indent war in Ruby?)

            • vemv 8 years ago

              Your observations are on point, and collaborating with lispers is not free of bitter moments.

              At work we use cljfmt (similar to gofmt) plus a variety of hacky formatters and conventions. It works for us and I hope to open-source part of our stack at some point!

              The experience is similar to that of Rubocop - which btw is the reason why there aren't indent wars (or similar) on Ruby.

              Great to decomplect how code is written (however you please), from how it is committed (autoformatted).

        • vemv 8 years ago

          By the way I agree with `There is a better thing, even if you must make it`!

          But I make those 'things' within lisp rather than by exploring new languages. If done sensibly, colleagues will be able to use those custom abstractions too.

      • flavio81 8 years ago

        >Lisps are arbitrarily powerful by the means of macros.

        This is my experiencie too. S-expressions + macros is an amazingly powerful combination.

  • vemv 8 years ago

    Similar sentiment here. Luckily I had the chance to move ruby->clojure professionally.

    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!

sadiqmmm 8 years ago

Awesome! :)

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection