• The REPL: Issue 76 - December 2020

    Command Line Interface Guidelines

    An open-source guide to help you write better command-line programs, taking traditional UNIX principles and updating them for the modern day.

    This is a great idea. CLI programs might not have a graphical interface, but there is still user experience to consider. This guides provides a starting point, with rationale behind the philosophy of the guide. In particular, I was pleasantly surprised by the author’s humbleness:

    It’s ironic that this document implores you to follow existing patterns, right alongside advice that contradicts decades of command-line tradition. We’re just as guilty of breaking the rules as anyone.

    The time might come when you, too, have to break the rules. Do so with intention and clarity of purpose.

    What Shape are You?

    The article has an interesting metaphor: In collaboration teams, the shape of your work is important. The work that someone does can leave gaps that can be left undone that no one else is really capable of doing. For example, if you don’t write tests or comment your code, it is really hard for the rest of the team to compensate and do that for you. They don’t have enough context.

    Another interesting concept is that some work can be either additive or subtractive. Additive would be something like making widgets. The more you do, the better. Software projects are subtractive: We keep working until we have done all the work that is left. In this sense, someone can do a lot of work in a team – even more than anyone else – but still leave gaps that prevent the project from succeeding.

    I don’t think the subtractive analogy is quite true: Software projects are not really a static set of work. It can grow and shrink, while still being successful. That is the reasoning behind MVPs, or prioritizing work to deliver value. In fact, the software projects that I work on, are not really ever done. The software continues to evolve. The author comes from a gaming background, which might explain a different mentality. In any case, software does have a subtractive quality to it: Some of the work needs to be done by someone, and a team member that leaves gaps requires others to take that up.

    Climbing Steep hills, or adopting Ruby 3 types with RBS

    Ruby 3.0 was just released. It includes RBS, a language to describe type signatures for Ruby programs. In this post Vladimir Dementyev explains in hands-on detail how to use RBS to add types to Ruby programs. The type system is designed to be gradual. It makes it easier to start adopting it. Of course, the more type information is provided, the more effective the type-checker is.

    Read on →

  • The REPL: Issue 75 - November 2020

    Why Ruby Class Methods Resist Refactoring

    Sasha Rezvina explores why class methods in Ruby are hard to refactor. They tend to accumulate lots of logic. I prefer limiting class methods to “builder” methods that instantiate new objects, like .initialize.

    Verbal Expressions: Ruby Regular Expressions made easy

    This looks like a fantastic library. It provides a way to “verbally” construct regular expressions:

    tester = VerEx.new do
      start_of_line
      find 'http'
      maybe 's'
      find '://'
      maybe 'www.'
      anything_but ' '
      end_of_line
    end
    
    tester =~ "https://www.google.com"
    

    It supports string replacement, and capture groups too!

    Moving my serverless project to Ruby on Rails

    This article illustrates one of my worries about the server-less trend: Each lambda function might be simple, but there interactions are not, and that is hard to reason about (and deploy!).

    When the building blocks are too simple, the complexity moves into the interaction between the blocks.

    Read on →

  • The REPL: Issue 74 - October 2020

    Introduction to the Zettelkasten Method

    The Zettelkasten method is a sort of personal note-taking method. This articles explains why the method is interesting in the first place, it’s principles and a few possible ways of using it. I’ve been gravitating in the last few years to a similar method, which doesn’t quite adhere to all the principles. I’ve long known that writing things down helps clarify your thoughts; having to articulate your thoughts, makes you a better thinker. It also helps with knowledge retention. What struck me most as I read this article is that there is another level of value that comes from the effect of capturing more things and linking thoughts together. That is what turns facts into knowledge: Knowing how it relates to other thoughts.

    As I was reading, I noticed that I often capture thoughts in my daily note. That is better than not capturing at all, but it doesn’t make it discoverable in the future. Since reading the article, I’ve started creating separate notes for each individual “thought” and tagging it. I am also making an effort to link – at the time of writing – with other notes.

    The Pyramid Principle

    Shiva Prabhakaran at Models HQ writes about the Pyramid Principle, which recommends that you start communicating with your answer/hypothesis first and then support it with arguments and data.

    My natural instinct when speaking, is to do something similar to this recommendation (but not quite): Start with the answer, and then add context. This recommendation goes a bit further: Answer, summary, and then supporting arguments.

    When writing, my instinct is more to start from the context, walk through the rationale and arguments, and then get to the conclusion. That follows my train of thought, which I expect my readers to follow. This article explains why it might be better to start in the other direction.

    The recommendation comes from consulting companies and their communication with executives. Its applicability might be limited.

    Rbspy

    This week I found myself working on optimizing the performance of a refactored Rails endpoint. I found rbspy:

    rbspy lets you profile Ruby processes that are already running. You give it a PID, and it starts profiling. It’s a sampling profiler, which means it’s low overhead and safe to run in production.

    rbspy lets you record profiling data, save the raw profiling data to disk, and then analyze it in a variety of different ways later on.

    This made it painless to get data on a running process without much fuzz. It even generates flamegraphs.

    Read on →

  • The REPL: Issue 73 - September 2020

    Under Deconstruction: The State of Shopify’s Monolith

    The engineering team at Shopify discuss the state of their Rails monolith, how it has evolved over time, the lessons they’ve learned and what is in store for the future. Most of the information is relevant for Rails developers working in large systems, with large teams.

    As part of their efforts to make their monolith more effective, they are introducing a newly-open sourced tool: Packwerk. The objective is to enforce modularity, through the use of static analysis.

    Writing a book: is it worth it?

    Martin Kleppmann discusses openly the economics of writing his book: Designing Data-Intensive Applications. The book has been one of my favorite technical books. The book has generated almost $500,000. It involved working on it for years – one of them without any other income, speaking at more than 50 conferences promoting the book, and was helped in no small part because of Kleppmann’s well deserved presence and reputation in the field.

    Read on →

  • The REPL: Issue 72 - August 2020

    Error handling with Monads in Ruby

    Vitaly Pushkar goes over error handling in programming languages and the reasoning for using monads for error handling. I’ve been experimenting with that at work record with very positive results – albeit in a limited portion of our code.

    There is a section where the author talks about the “pyramid of doom” – much like the dry-monads documentation. The “do notation” is presented as a solution. Maybe it’s my lack of familiarity with that notation, but I think that there is a simpler solution, which I call “railway oriented”.

    Pyramid of Doom:

    def call(fields)
      validate_fields(fields).bind do |fields|
        validate_email(fields['email']).bind do |email|
          find_user(fields['id']).bind do |user|
            update_user(user, {name: fields['name'], email: fields['email']}).bind do |user|
              send_email(user, :profile_updated).bind do |sent|
                Success(user)
              end
            end
          end
        end
      end
    end
    

    Do notation:

    def call(fields)
      fields = yield validate_fields(fields)
      email = yield validate_email(fields['email'])
      user = yield find_user(fields['id'])
      user = yield update_user(user, {name: fields['name'], email: fields['email']})
      sent = yield send_email(user, :profile_updated)
    
      Success(user)
    end
    

    Note that the yield in the above solution differs from the standard Ruby meaning. It doesn’t yield to the block passed to #call but rather binds the Result and halts execution of the method on failures.

    My “railway oriented” solution:

    def call(fields)
      validate_fields(fields).
        bind { |fields| validate_email(fields['email']) }.
        bind { |_email| find_user(fields['id']) }.
        bind { |user| update_user(user, {name: fields['name'], email: fields['email']}) }.
        bind { |user| send_email(user, :profile_updated) }
    end
    

    The “pyramid of doom” is avoided, without having to change the Ruby semantics.

    How to stop procrastinating by using the Fogg Behavior Model

    The Fogg Behavior Model is a new concept for me. It presents a mental model in which:

    Behaviour = Motivation + Ability + Trigger
    

    A lack in any of the three factors can prevent behavior from occurring. The articles then talks about different strategies to boost each factor. For example, blocking time in your calendar can serve as a trigger to start working on a particular task. I’ve been very successful with that technique lately.

    Read on →