Never miss an update:

  • tmux configuration from scratch

    I started using vim together with tmux a couple of months ago. After surviving my first week, I organized a workshop to share what I learned with the rest of the team and convince the resistors to switch. :)

    This post will focus on tmux, but stay tuned for a follow-up post about vim!

    tmux

    Basic setup

    First things first, so what’s tmux? Well, taken from their own documentation:

    Tmux is a terminal multiplexer which lets you switch easily between several programs in one terminal, detach them and reattach them to a different terminal.

    Which basically makes your terminal look like this:

    tmux basic setup

    Now you might be wondering, what’s the difference between tmux and what I have now?

    For many people, the main reason to use tmux windows over tabbed terminals is that with regular terminals, if the window manager crashes, you’ll lose the terminals as well. However, this won’t happen with tmux, which keeps the terminals running in the background. You can re-attach a new terminal to them at any time. What I also like about it is that I can create sessions for each of my projects. This keeps them organized and makes it very easy to switch between them, so you can find projects exactly where you left them. ;)

    Awesome! To start using tmux you need to install it first. If you are already using Homebrew to manage your packages, you can just run:

    $ brew install tmux

    Below I will guide you through some changes in the configuration to make it behave in a more intuitive way. These changes need to be done in the ~/.tmux.conf file, so if you still don’t have that file, go and create it now:

    $ touch ~/.tmux.conf

    Meeting the “prefix”

    First of all let me introduce you to “prefix” because every time that you want to “speak” to tmux you will need to use it. Its default value is Ctrl+b, but it can be changed to any keybinding that best fits your fingers. ;) In my case, I decided to bind it to Ctrl+s:

    # ~/.tmux.conf
    unbind C-b
    set -g prefix C-s

    At this point it can also be quite useful to remap the Caps Lock key to Control. If you are using Mac you need to go to the section Modifier Keys under your Keyboard preferences and select Control for Caps Lock.

    Finding a friend

    While I was hunting for some inspiration before deciding to give tmux and vim a shot, I came across this talk by Mike Coutermarsh in which he shares some very good tips. This is one of them: copy the configuration file from a friend. He is referring to vimrc, but it also counts for the tmux.conf file. You can have a look at my configuration here, which is a modified version of Thoughtbot’s and Mike Coutermarsh’s.

    Reloading the configuration

    Whenever you find yourself making any changes in the configuration, don’t forget to reload it by running:

    $ tmux source-file ~/.tmux.conf

    Which I have bound to <prefix> r:

    # ~/.tmux.conf
    bind-key r source-file ~/.tmux.conf \; display-message "~/.tmux.conf reloaded"

    tmux objects overview

    Before we move on with some other configuration tips, let’s talk briefly about some important concepts that will help you understand how tmux works.

    Session

    The first concept to be aware of is sessions. A session refers to a named collection of one or more windows. Typically I will create one session for each of my projects and give it the name of the project.

    sessions overview

    Window

    Next comes windows. A window refers to a single screen within tmux, similar to tabs in terminal applications or browsers. Remember that at any given time, a client will be attached to a single window.

    Pane

    Last but not least, we find panes. A pane refers to a portion of a window running a single process, e.g. vim, rails server, rails console, etc. Panes can be oriented either vertically or horizontally and resized as needed.

    windows and panes

    Now you might be curious about what my screen looks like with so many possibilities between sessions, windows and panes.

    As a Rails developer what I found to be working for me is to have vim in a first window along with a right-side pane for committing code to Github or running tests. Any background process, like the rails server, workers or Elasticsearch, is running in an additional window, together with the rails console.

    Some commands to remember

    Below is a list of the most important commands I use on a daily basis. It might feel overwhelming at first, but you will get the hang of it sooner than you think. Believe me!

    Sessions

    # create a new session
    $ tmux new-session -s {name}
    # list out sessions and a brief summary
    $ tmux ls
    # kill/delete session
    $ tmux kill-session -t {name}
    # list out sessions and switch easily between them
    <prefix> s
    # disconnect/dettach tmux client while keeping the session alive
    <prefix> d

    Windows

    # create a new window
    <prefix> c
    # go to next window
    <prefix> n
    # go to previous window
    <prefix> p
    # go to last window
    <prefix> l

    By default, windows will open in the directory of the current session. This will allow them to open in the directory of the current pane:

    # ~/.tmux.conf
    bind c new-window -c "#{pane_current_path}"

    Panes

    You can create and split panes in a more intuitive way by adding the following configuration, making sure that it remembers the current path as well:

    # ~/.tmux.conf
    bind-key - split-window -v -c '#{pane_current_path}'
    bind-key \ split-window -h -c '#{pane_current_path}'

    Which turns on these key bindings:

    # split window vertically
    <prefix> -
    # split window horizontally
    <prefix> \
    # kill pane
    <prefix> x

    Adding the following configuration allows you to navigate your vim splits and tmux panes at the same time by using the keys Ctrl + h/j/k/l, so no more need for the prefix with these ones:

    # ~/.tmux.conf
    is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$"'
    
    bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
    bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
    bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
    bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"

    You can resize the active pane with Shift + L/R/D/U (which refers to each of the arrows keys). The related configuration to enable those is:

    # ~/.tmux.conf
    bind -n S-Left resize-pane -L 2
    bind -n S-Right resize-pane -R 2
    bind -n S-Down resize-pane -D 1
    bind -n S-Up resize-pane -U 1

    I find it also very useful to focus on the contents of a single pane temporarily and unzoom as needed. The <prefix> z command acts as a toggle to both zoom a pane and unzoom. Try it out!

    Wrapping up

    Now it’s your turn! After these notes, I think you are ready to start playing around with tmux, which might be hard at first. My best advice is to not think about it too much - just go for it and stick with it!

    Read more
  • Social Engineering: Communication Skills for Technical People

    We’ve been documenting the effect of stereotypes and bias in relation to issues of race and gender for a long time. When students are primed to believe that boys are better than girls at math, for example, the boys will outperform the girls. But when they’re told boys and girls are equally capable at math, the scores even out.

    As software engineers, we’re often faced with the stereotype that technology is the polar opposite of the communications world. Just look at how engineers are portrayed in the media - from HBO’s Silicon Valley to the Big Bang Theory, it’s almost like poor social skills are a prerequisite for doing our job.

    silicon valley

    At the same time, marketers and business people are told that technology is a “hard” skill while they are “soft” skill experts. This fosters an environment where business folks fail to develop basic technical knowledge that could greatly benefit their career.

    The good news is: We can outsmart stereotypes. Let’s throw away the notion that communication skills and technical skills are incompatible. Instead, let’s accept that we live in a collaborative digital world in which both skill sets have an equal and important place.

    But seriously, why should engineers care about “soft” skills?

    Ok, we all know that coding is all about sitting alone in a dark room hacking at a mainframe, right?

    hacking the mainframe

    Of course not. These days, big projects are accomplished by teams of engineers, designers, business types, and financial stakeholders. We’re constantly communicating with members inside and outside our team to establish workflows, give feedback on code, create mockups, finalize requirements, establish timelines, and conceptualize codebase architecture.

    Effective communication allows everyone to get their job done efficiently - with minimal missed connections and unnecessary back-and-forths. It means setting expectations for everyone around you, allowing business owners to allocate resources appropriately and plan their own projects around accurate development timelines.

    Regardless, even if you DO want to hack the mainframe, there are countless awesome projects you can tackle as a technical person with superb communication skills. For example, when brainstorming a title for this post, I thought back to my enterprise security marketing days. Social Engineering is an attack vector that relies on human communication - tricking the doorman into letting you into someone’s server room, for example.

    Clearly, when you’re a software engineer AND an expert communicator, world domination is right around the corner.

    Your Communication Skill Set

    A process by which information is exchanged through a common set of symbols, signs, or behavior. - Merriam-Webster.

    If this definition sounds familiar, that’s because it is. The dictionary definition of communication is essentially a verbatim description of software development. In truth, we technical folks are already great communicators whether we think so or not. It’s just that our language of choice is Ruby, JavaScript, or C instead of English, Dutch, or Chinese.

    Embracing this parallel allows us to apply the same concepts we use to get better at programming to build our skills as great communicators.

    It also means that in the end, like programming, we can improve by following reusable, predictable patterns and guidelines. It just takes a bit of conscious time and effort, and the realization that “soft” skills are a key asset in our professional toolbox.

    Here are 3 focus areas that can make a significant impact for software engineers:

    Jargon

    Jargon just means language that is not well understood outside of a specific context. As software developers, we often forget how many of our words and phrases constitute technical jargon. We casually throw out words like database or the names of services like GitHub or AWS all the time. And in engineering circles, that’s fine!

    But what happens when you’re trying to explain a project to one of your designers, a marketer, or your CEO? Jargon becomes a big issue.

    1. Be aware
      • It sounds cliche, but this is the best thing you can do to avoid overuse of jargon in non-technical contexts. Just watch yourself, be aware - if someone looks confused, ask them why, and see if technical jargon is the culprit.
    2. Translate
      • When you discover a piece of jargon and a nice non-technical translation, write it down! Maybe create a little command line program for yourself to save the translations and look them up later.
    3. Know your audience
      • Do you need to give a presentation to the marketing team? A designer? A venture capitalist? Your audience might use jargon of their own, and if you can learn it beforehand and use it correctly, you can boost the weight and clarity of your message accordingly. For example, maybe the business folks at your company speak in terms of ROI and KPIs - it’s up to you to find out.

    Grammar & Syntax

    How many of us have accidentally sent out a really important email to a really important person, only to realize one second later that it contained a super embarrassing grammatical mistake?

    …and why was that experience horrifying?

    Because it makes us look stupid!

    Especially with our native language, grammar is the easiest and hardest thing to get better at all at once - mainly because we take it for granted. The truth is, most of us haven’t studied the language we speak and write in for many years, and there are words and rules we certainly knew back in grade school that we no longer remember today.

    How to improve:

    Sitting down with a book on grammar, a thesaurus, or an online writing tool is the equivalent of sitting down with the Ruby documentation or a book on programming style. Doing so will help you sound more intelligent by making your sentences clearer and your vocabulary more precise. (See, it’s that easy!)

    No but seriously, the hardest part is just taking the time to do it.

    Tone

    The word tone literally pertains to the rising pitch of your voice. Tone has a significant impact on the quality of our communication, because the same words can be interpreted in very different ways depending on the pitch of your voice.

    Was your comment offensive, friendly, angry, helpful, or sarcastic? Will this create more work for you later, because so-and-so needs to have a sit down talk about the tone of your latest email?

    How to improve:

    1. Read Aloud
      • One of the best ways to improve tone is to read your thoughts aloud. Even better - read them to a friend, and see how they interpret your tone. This is especially important when working with a second language, as tone can be highly dependent on cultural norms that may not be familiar to you.
    2. Refactor
      • Style affects tone, and improving writing style follows similar rules to refactoring code. Keep sentences short (8-12 words), leave white space between paragraphs, use punctuation appropriately, and use special formatting sparingly.
    3. Reflect
      • Even when writing, your emotions will come out in the tone of the language you use. If you’re feeling emotional - overly excited, angry, or nervous - it’s ok to put off an in-person meeting or important message for a day. If you absolutely need to communicate immediately, write your thoughts down, read, and refactor, making a conscious effort to come across in a tone that works to your advantage.

    Setting Expectations

    Now we loop back to what all this work comes down to: setting expectations. When we communicate effectively, the people we work with know what to expect from us and our team. Projects move forward with the resources they need, and we can all get our jobs done efficiently.

    This isn’t about how you say something, but WHAT you say.

    How to improve:

    1. Clarify requirements
      • A lot of people really suck at communicating, and we can accept and work around that to our advantage. This is especially true when non-technical people give project requirements, and your biggest task in this scenario is to ask questions.
    2. Say “I’ll get back to you”
      • Figuring out how to estimate software projects takes time and mental effort. Give yourself time to think. If someone comes to you asking for an estimate or your thoughts on a new project, practice saying, “I need to look into X, Y, and Z - let me get back to you on that”. Research done upfront can help you avoid time-intensive backtracks down the road.
    3. Continue communicating
      • Especially with software projects, it’s not until we dive into the codebase that we figure out how long something will take, and that’s ok. Just remember that as software developers, we are often the ONLY members of our team with access to the codebase and the ONLY ones who understand this aspect of our job. It’s therefore our responsibility to communicate what’s going on, as soon as possible. Never feel guilty for bringing up that a project will take longer than you originally thought - so long as everyone knows what to expect, deadlines and resources can be moved around in time.

    Can you update some website copy for me?

    Sounds great. Where is that copy? Can you show me that page on the website? Do I need to write the copy? Does this need to be reviewed? Will this copy change again in the near future? Does it need to be up on the staging website first? Is this copy saved as text, or is it an overlay on an image somewhere…?

    Tomorrow’s TODO List

    Communication skills can be improved with just a small amount of effort on our part, and it’s something we can work on over time - just like learning a new programming language, or picking up Vim.

    1. Call the least tech-savvy person you know - Explain your latest project, then ask them to explain it back to you. Did they really “get” it? Did you find any words for your jargon translator?
    2. Read your docs - Skim a grammar guide for concepts you forgot you knew.
    3. Learn a new vocabulary word - Find a word that is a more precise version of a word you’re using now.
    4. Estimate coding time - Take a guess at how long one task will take you, start to finish. Compare after your production deployment, and see how well you did.

    In the end, my hope is to break down the “soft skilled people” vs. “hard skilled people” stereotypes, and instead focus on how both sides can foster an environment where technically skilled, communicative developers can more efficiently build bigger, better collaborative projects.

    This blog post was adapted from my talk at NLHTML5, and you can check out the slides here.

    Don’t forget to also follow us on Twitter @SpringestOps, where we practice our communication skills on the regular.

    Read more
  • Forwarding a webhook to multiple endpoints

    We have a growing support team and recently started work on an internal tool to help them better serve our users, this combines data from our main application and Helpscout, which we use extensively. We initially worked with scheduled API imports but quickly felt the need for real-time data coming in from Helpscout via webhooks. Unfortunately they only support setting up a single endpoint for their webhooks, as do some other services. As this endpoint was already in use, this posed a problem.

    To solve this issue, we decided to build something to mirror these incoming webhooks to any number of endpoints. Normally with webhooks you will want to verify that an incoming request was actually from the configured service by using a shared secret key to hash the body with, so the goal was to mirror it exactly, using the same headers and POST body.

    Trying out Lambda

    We actually started out with a solution on AWS Lambda running on Node, but the problem there was that you do not get easy access to the headers and request body, and have to define mapping templates. That ended up slightly changing the body, escaping http:// as http:\/\/ for example, which of course changes the verification signature.

    So back to the drawing board, Lambda seemed really awesome as you don’t have any servers to take care of, and webhooks really seem to fit nicely, but the Amazon API Gateway that needs to be in front of it felt annoying and tough to configure, we really wanted easy access to the raw request, and configure everything in code over clicking through endless and identical-looking forms.

    Forwardhook

    We decided to write Forwardhook using Go and it’s been serving our needs since. We are running this on AWS Container Services using our provided docker image. We picked Go as we like the benefits of a single binary, cross-compiliation and the low resource usage.

    As the goal is quite simple, this tool is as well. It mirrors incoming requests, using the same headers and body, and will retry a failed connection up to 10 times. Failing requests (non-20x) are not retried. Besides this it’s fire and forget, so we are always returning a 200 to the original requester.

    Endpoints are configurable via FORWARDHOOK_SITES, which makes it easy to spin up multiple containers to point to other endpoints. We have two running at the moment for our Helpscout accounts as they are currently split up per country. A possible improvement could be to configure the endpoints via query parameters, to be able to run a single instance for however many webhooks you need. For now, we simply run two containers and listen on two seperate ports.

    So give it a spin if you ever need to mirror incoming webhooks to multiple locations! :-)

    Read more
  • Working at Springest (video)

    At Springest we pride ourselves on our company culture and Frissr made a nice video of it. A big part of the video is about what it’s like to work as a developer at Springest.

    Interested in working at Springest? Check out our vacancy for a senior ruby on rails developer.

    Read more
  • Exploring the Simple Form Gem

    During my first months at Springest, as a fast-learning junior developer, I will be diving into the workings and usage of popular gems and posting here my experiences with each of them once in a while. Simple Form is the gem of this week!

    Forms are essential for user input in web applications. However, they can become tedious to write and maintain because of the need to handle form control naming and its numerous attributes.

    That’s where the Simple Form gem comes in handy. It aims to be as flexible as possible while helping you with powerful components to create your forms. And don’t worry, because you will still be able to define your layout the way you do now.

    What We Are Building

    In this article we will be building a model-centric form for creating and editing companies including the following fields: a text field for its name, a text area for its description, a select box for its size (number of employees) and a checkboxes collection for its different categories.

    Defining Relationships Between Models

    To be able to build this form we will first need a company and a category models. Beside these two models we will also have a characterization join model, which will be in charge of connecting the company and the category models. Any particular row in the characterizations table will effectively join a row in the companies table and a row in the categories table.

    Check out the following diagram showing the models associations:

    The following code shows the corresponding validations and how the structure would look like:

    class Company < ActiveRecord::Base
      has_many :characterizations, dependent: :destroy
      has_many :categories, through: :characterizations
    
      SIZES = ["0-10", "11-30", "31-50", "More than 50"]
    
      validates :name, presence: true, uniqueness: true
      validates :description, presence: true
      validates :size, presence: true, inclusion: { in: SIZES }
    end
    
    class Category < ActiveRecord::Base
      has_many :characterizations, dependent: :destroy
      has_many :companies, through: :characterizations
    
      validates :name, presence: true, uniqueness: true
    end
    
    class Characterization < ActiveRecord::Base
      belongs_to :company
      belongs_to :category
    end

    Let’s Build the Form

    I will be guiding you through the different form helpers in Simple Form and how to use them compared to the built-in Rails Form Builder.

    The form will be scoped to the company model and to start using Simple Form you just have to add the helper it provides:

    <%= simple_form_for @company do |f| %>

    Adding a Text Field and a Text Area

    When using the Rails Form Builder you need to specify one by one the type for each of the different form helpers and add a corresponding label to them. For the text and the text area fields you then have to pass in the name of the attribute to be called on the company object (name and description in this case).

    <%= f.label :name %>
    <%= f.text_field :name %>
    
    <%= f.label :description %>
    <%= f.text_area :description %>

    One of the nicest things about Simple Form is that you don’t need to specify the type of the different form elements, but it will figure that out by itself looking at the column type in the database and use an appropriate input for the column. For example, a column created with type :text in the database (like the company’s description in our case) will use a textarea input by default. You can check here a complete list of the available input types and defaults for each column type.

    A label element will also be added by default to each of the fields, transforming the above code into this:

    <%= f.input :name %>
    <%= f.input :description %>

    Adding a Select Box

    In the case of a select box, Rails Form Builder will also need the options array to be passed in as a second parameter.

    <%= f.label :size %>
    <%= f.select :size, Company::SIZES %>

    With Simple Form if you want to create a select containing the different sizes of a company you can do it overriding the :collection option. Collections can be arrays or ranges, and when a :collection is given the :select input will be rendered by default, so no need to pass the as: :select option:

    <%= f.input :size, collection: Company::SIZES, prompt: "- Select number of employees" %>

    Adding a Checkboxes Collection

    To generate a collection of checkboxes with Rails Form Builder we will need to pass in the following parameters to the form helper:

    • Name of the attribute or method to be called on the company object (as in the previous form elements)
    • Options array or collection to be shown
    • Name of the attribute to be used as the checkbox value
    • Name of the attribute to be used as the checkbox label text
    <%= f.label :categories %><br>
    <%= f.collection_check_boxes(:category_ids, Category.all, :id, :name) %>

    To deal with these type of associations, Simple Form can generate either select inputs or a series of radios buttons or checkboxes. We will only need to pass in the categories collection as a parameter. The association helper would render a :select input by default, which can be changed into radio buttons or checkboxes like we did in this case:

    <%= f.association :categories, as: :check_boxes %>

    What We Got

    Our form will end up looking very short and simple indeed ☺ :

    <%= simple_form_for @company do |f| %>
      <%= f.input :name %>
      <%= f.input :description %>
      <%= f.input :size, collection: Company::SIZES, prompt: "- Select number of employees" %>
      <%= f.association :categories, as: :check_boxes %>
      <%= f.button :submit %>
    <% end %>

    What’s Next

    If you didn’t have enough and you are actually interested in doing more complicated things with Simple Form, you will be happy to hear that:

    Read more

subscribe via RSS