1. 1

    TBH, I feel that’s a pretty ugly workaround to avoid fixing the real problems of a slow exception mechanism and an inconsistent library interface.

    1. 1

      If you read the issue tracker, the performance bit is really secondary to avoiding debug output by jumping through hoops. I think the author took the wrong part to highlight in their write up.

      Exception performance is not the problem to be solved here - exceptions are intended to be, well, exceptional and using them for flow control rather than error handling is a bit of a smell.

      As far as the inconsistent interface, conversion functions have consistency and aren’t intended to mirror implicit casting methods. It’s been a while since I’ve read Confident Ruby, but as I recall it covers the topic really well. Let’s also say that hypothetically you were to resolve that inconsistency - that would be a breaking change which is in all likelihood not worth the cost. This change is backwards compatible, solves the problem of jumping through hoops to avoid debug output, and is consistent in the conversion function interface.

      Now, whether this is something a lot of Rubyists will need to know or care about… probably not. I’d relegate this to the realm of Ruby trivia for a very select set of problems. It’s a good change, though.

    1. 12

      I think the title buries the lede (but was clickbaity enough for me to be interested). As stated in the article:

      The point of the comparison isn’t that Elastic Transcoder is a ripoff, it’s that Lambda can often result in significant cost savings if you have a well-defined use case that’s compatible with the limitations that Lambda imposes.

      The tip about using Exodus alone was really helpful - I learned a new thing that could be super-useful where I previously would have gone down the rabbit hole of compiling native binaries on the Lambda AMI. Good stuff!

      1. 2

        as a non ruby programmer I wonder: What do you all need infinite ranges for that you need a special syntax for it. I think I never had a need for that. So I wonder, what are they used for?

        1. 2

          How about a game loop that keeps track of ticks?

          As a Ruby programmer I have definitely written infinite ranges a handful of times - it does come up, though it’s not common.

          1. 1

            there are examples in the blog post, but (also as a non ruby programmer) I don’t find any of them particularly compelling

            1. 1

              I am a Ruby programmer, and I’m also not sure what people need infinite ranges for so often.

              1. 1

                I use them, but that’s probably me porting Hasellisms to Ruby more than a common Rubyism. Things like: (0..1.0/0).zip(array)

                1. 1

                  Yeah it’s probably more Ruby-ist to use each_with_index for that, but it’s interesting that that works.

            1. 3

              If you want to avoid metaprogramming then I recommend setting up a snippet in your editor that expands to a memoized method. For example, when I type memo<TAB> (I use UltiSnips) then the following appears:

              def name
                @name ||= value
              end
              

              UltiSnips keeps name in sync both in the method name and attribute name. Pressing <TAB> one more time takes me to value. You can of course do the same for the more bullet-proof approach described in the article.

              1. 2

                That’s a good point. I do use RubyMine live templates, and there’s a way to do something like that in most editors.

              1. 3

                Another anti-pattern is making the Controller instance manage the Serializer. Ideally, the Controller just returns an object, and any need to transform that object to a specific format is handled decoratively or via DI. Transformations don’t belong in business logic.

                1. 4

                  I somewhat regret using a controller as the example, because this is applicable to any Ruby object. Its so easy to get into controller analysis rather than my main gist.

                  1. 1

                    My rule still applies- controller or not, they should just return the structure that makes sense to them. If it doesn’t make sense to the consumer, put a layer of indirection between them. As much as I am wary of indirection, objects should do what makes sense to the object.

                1. 6

                  I’ve seen a similar thing with tests written in rspec where lets are exclusively used in place of local variables. Any thoughts on how to strike the balance there?

                  1. 5

                    YES! This advice completely applies to let variables in RSpec tests too. A let is a memoized method definition in my book. I am happy to recommend using more local variables over let variables in tests.

                  1. 3

                    I am not satisfied by this argument.

                    I don’t think unseating rails is easy, and the author’s prediction may very well come true, I don’t agree with the reasoning for why. Inertia is powerful, brainshare is hard to overcome.

                    Dumping any semblance of what folks call “magic” as a discriminator isn’t what is going to win folks over. I can’t say for certain what will, except that having unique and clear advantages will help. It’s about timing, luck, effort, money, and ideas.

                    1. 3

                      Maybe this will sound ridiculous, but is there a good reason to not allow wild-west tagging? I get that this community has a curated bend to it, but what would the drawbacks be of opening that up?

                      1. 10

                        I think the idea is that if it doesn’t fit an existing tag the post is off-topic. Tag creation references posts that I guess we’re agreeing as a community were on-topic but had to be shoehorned in to existing tags.

                        I’ve at least on one or two occasions ran in to a story that I couldn’t really fit in a tag so skipped submitting. Overall I like the approach.

                        1. 2

                          Ah yeah, that’s right. Welp, it was a crackpot idea after all :) Thanks for reminding me of the signal provided by tags, it’s surely useful.

                      1. 5

                        I’m working on a Ruby talk called “Metaprogramming with super powers” that I’m giving at the Indianapolis Ruby Brigade meetup on Valentine’s Day. Sadly it was rejected from RailsConf, so I’m 0/4 on my conference talk submissions - just gonna keep working the meetup circuit.

                        Also working on some finishing touches on an Instrumentation gem based loosely on my blog post on instrumenting Ruby methods. I released 1.0 last Friday, but there’s still some improvements I want to make. It’s not currently open source, but may be suitable to release at some point.

                        1. 2

                          It has been bothering me that I used the word ‘fake’ in the title rather than something more-accurate such as ‘misleading’. It is possible to achieve records using emulation, and can still be an accomplishment IF there’s no abuse of emulation features that allow “rewinding” or other cheats not possible in the “regular” course of gameplay.

                          There’s a huge amount of drama that goes along with these records and Billy Mitchell that I have zero stake in - as mentioned in the submission the aspect I found most-interesting here was the breakdown of MAME vs original.

                          1. 1

                            I noticed that this library is performance tested, with assert statements that make sure that a given function is executed within X ms.

                            Are these kinds of tests helpful? Does it not make a difference what machine the tests are running on? Or if the test runner instance is responsible for running other test suites too and happened to be overloaded at the time these performance tests ran?

                            Or is there a way to isolate machine resources so that such tests yield predictable/consistent results?

                            1. 1

                              I’d say they are useful for preventing performance regression. They are likely fairly consistent, but it is true that there’s potential signal pollution that can occur.

                              1. 1

                                Exactly. I’ve done this type of assertion before and you wind up having to put such a wide margin of error in it (like order of magnitude with modern, cloud CI boxes) that it doesn’t catch anything but the most egregious of regressions.

                                That said, you can still assert relative comparisons (assert my time < “other gem” time) with some confidence.

                                1. 2

                                  Ug I missed that. Well-spotted

                                1. 2

                                  FWIW the author discussed this idea on Twitter with Matz:

                                  Nick Sutterer (@apotonick): Hi @yukihiro_matz - what do you think about this? https://apotonick.wordpress.com/2018/01/17/dear-ruby-1-what-about-arguments-when-inheriting/ (I’m probably not the first one with this idea?!)

                                  Yukihiro Matsumoto (@yukihiro_matz): @apotonick How about generating a class to be a superclass?

                                  class Foo<Bar(args) … end

                                  where Bar() is a method that returns a class.

                                  Nick Sutterer (@apotonick): @yukihiro_matz Yes, that’s the current approach in many gems. However, this implies some meta programming and an anonymous class, whereas the extended ::included signature would be consistent and in-line with #initialize, right? Thanks Matz!

                                  Yukihiro Matsumoto (@yukihiro_matz): @apotonick I am afraid that I don’t share that “consistent and in-line with” feeling.

                                  Nick Sutterer (@apotonick): @yukihiro_matz 😬 It’s “create an intermediate, anonymous class between A and subclass B” vs. “allow passing explicit arguments and set variables on B after B is inherited, the way you do it when creating object instances”

                                  Nick Sutterer (@apotonick): @yukihiro_matz Ok, let’s forget the “consistent” argument. What’s better: passing arguments to a method, or having to create a temporary anonymous class to transport those arguments?

                                  Yukihiro Matsumoto (@yukihiro_matz): @apotonick Yours consumes less memory. That is good. But it may make the language more complex.

                                  Besides that, considering potential code breakage, I cannot simply say yours is “better”.

                                  Nick Sutterer (@apotonick): @yukihiro_matz Thanks, agreeing. ✌️My idea introduces a syntactical change, true. Does that make the language more complex? Yes.

                                  Creating an intermediate class instead: makes the USE of the language more complex.

                                  Could there be any incompat, though? 🤔🤓🧐

                                  Yukihiro Matsumoto (@yukihiro_matz): @apotonick Your particular example

                                  class Memo::Render < Render, engine: Render::JSON … end

                                  does not conflict with existing syntax (due to the comma after ‘Render’), but I am not positive with a comma here because it reminds me multiple inheritance.

                                  Nick Sutterer (@apotonick): @yukihiro_matz Many thanks, I will elaborate more on this idea and talk to other gem authors about whether or not it would be cool to have that, etc. So there is no other proposal for this, yet? Haha, maybe I’m crazy 🤪 thanks!

                                  1. 2

                                    Here’s the approach Matz is referring to: https://gist.github.com/bkudria/82e3721d4ec2b62a2a3d95050e964d84

                                  1. 6

                                    A super rough rule of thumb: use getters if you need to perform logic to determine the property. Use setters if you need to maintain a class invariant. Otherwise use direct access.

                                    1. 8

                                      Always using methods for access is a type of future proofing since you can never be sure when you may need to add logic around access, and so a method is more tolerant of change over time. The interface changes if you switch from property access to method access in Java.

                                      I have no strong opinion, though, since I see it as a judgement call.

                                      1. 8

                                        My question is how often has the working programmer ever had to do that? I don’t remember ever doing this in all my years of software. Not once have I been able to take advantage of the fake insurance policy that getters and setters provide.

                                        Well, I have had to do it before. Maybe the author writes more green field stuff than maintaining systems.

                                        1. 2

                                          In most cases, you’ve got the source code that uses the object. Just change the code.

                                          1. 1

                                            Less-helpful for writing libraries used by several code bases - also something I have done several times. This is why it’s a judgement call to me. You are in a better place to predict how your code will be used than I am.

                                      1. 3

                                        I’m feeling like crustaceans don’t care about Ruby any more based on my recent Ruby stories submitted. Hell, even Matz tweeted a link to this post - but very little attention here. What’s with that?

                                        1. 5

                                          I think that Ruby is generally waning. The smaller regional conferences are disappearing (MountainWest, KRW, Ruby on Ales, Ruby Midwest, Ancient City…), the Google searches are dropping, the StackOverflow tag is dropping, a number of the most prominent Rails/big gem contributors have partially or wholly moved off to other languages. I haven’t made time to play with the RubyGems data, but I expect downloads to be flat or declining and new gems/releases to be declining.

                                          My best guess is that it’s because Ruby’s popularity is mostly driven by Rails, and Rails didn’t have a great story integrating the big increase in frontend complexity that started with the wave of libraries like Angular in 2009-2010. A lesser factor is that a lot of the attributes that make Ruby so fun for small scripts and quick for prototypes are anti-features for large, long-lived codebases, so folks are rewriting rather than maintaining. Or maybe it’s just a fad that’s fading; programmers are certainly not immune to marketing.

                                          1. 2

                                            I think the hype cycle is over for Ruby/Rails. The early adopters who shaped some of the popular projects have moved on because it’s more fun for them to trailblaze in a new community than it is to maintain things in a more-mature community. There’s still a hell of a lot of active rubyists, but maybe they’re no longer present here as much as they used to be.

                                            I appreciate your thoughtful response with links and data :) Interpretation is debatable, e.g. I think npm is a cesspool of microlibraries that don’t indicate healthy library development activity.

                                            I do wonder if I should continue posting Ruby links given little positive reinforcement that people care about them.

                                            1. 5

                                              I like that Lobsters has a lot of niche-interest stories. I’m a little sad to see Ruby returning to niche status, but that doesn’t mean these things are off-topic or not worth discussing.

                                          2. 3

                                            I can think of a couple of reasons:

                                            • In general, most language posts don’t get a whole lot of upvotes. You just have a more limited audience in a specific language than in a programming topic.
                                            • The article is about a couple of small methods added to Ruby. That’s interesting, I guess, but reading it doesn’t make me a better programmer. I doesn’t give me any sort of insight or inspiration or entertainment beyond “oh, okay.” Compare this, which is about security via Ruby, or this which is about how small differences between languages can slow you down. They’re highly upvoted in part because they’re worth reading even if you’re not a Rubyist.
                                            1. 1

                                              Thanks for your reasoned response. If I’m being completely honest, this is likely a knee jerk from my own post being overlooked which I’m over-sensitive about since I just barely started writing again.

                                          1. 7

                                            Wow this really exploded! Just a heads up to anybody creating an account, use joinmastodon.org and find a different instance than mastodon.social, it aint really decentralized if everybody is on the same server!

                                            1. 1

                                              I didn’t think much about it when I signed up. Is there a good way to migrate to other servers? I did dig up this github issue which AFAICT is unresolved - limitations of the protocol?

                                              Maybe I ought to just hop to another server before I’m too invested in my meager presence on mastodon.social

                                              1. 3

                                                Go in settings and export your follow list, then import into your new account. I think thats all you can do right now, but I still recommend it, as mastodon.social tends to go down everytime there’s a big twitter migration.

                                                1. 1

                                                  Did that and it worked fine.

                                                  I don’t care about keeping my old toots, though. I consider my social media stuff ephemeral. Auto-deleting is not implemented unfortunately…

                                                2. 1

                                                  kensanata also wrote a backup tool for all your toots etc. here: https://github.com/kensanata/mastodon-backup

                                              1. 3

                                                @soulcutter@mastodon.social

                                                Thanks for posting this - a barrier to adoption for me is discovering people on there to follow.

                                                1. 2

                                                  You may come to the point, where you to have certain elements that are bound to your model but don’t belong either there nor in the controller.

                                                  I don’t follow why they don’t belong in the model. These are behaviors that change the state of the model - it’s deeply coupled to attributes provided by the model. I am not convinced this is an example of good design, though it does cover the mechanics of how you can use that feature.

                                                  1. 3

                                                    Ironic that none of the table examples render properly on my phone…

                                                    1. 1

                                                      What phone/browser?

                                                      This does seem fairly cutting-edge since I cannot even find font-variant-numeric in caniuse search - there’s some discussion about it on github.

                                                      It’s disappointing to have found this and thought “Cool! This will be useful!” and then discovering it’s poorly-supported.

                                                      1. 2

                                                        On iPhone, all the table cells are rendered in a vertical list.

                                                        Header1
                                                        Header2
                                                        Header3
                                                        Data1
                                                        Data2
                                                        Data3
                                                        
                                                    1. 3

                                                      I am not sold on some of the approaches outlined here - e.g. OpenStruct is a scourge that has no place in 99.9% of Ruby code. Also there’s a lot of ActiveSupport-related advices in here, which is an unnecessary dependency in many cases.

                                                      All in all, I don’t think this post shows the best solutions, but it DOES show some solutions that are commonly-encountered.

                                                      How do YOU approach configuration?

                                                      1. 1

                                                        Welp, it looks like nobody is going to jump in and contribute, so let me put forth one good Ruby solution: dry-configurable