Ylan Segal

Book Review: The Ruby Way

Probably one of the most well-known books among rubyists, “The Ruby Way” by Hal Fulton with André Arko, has now been updated and released in its third edition. The first part of the book is dedicated to the language itself and covers syntax, semantics, some comparison to other languages and specific issues, like garbage collection, that developers are well served to know when writing ruby.

We do find OOP to be a useful tool and a meaningful way of thinking about problems; we do not claim that it cures cancer

The Ruby Way

The majority of the book is divided into sections that deal with specific task that a developer may encounter. From basics like working with String, numerical calculations and Enumerable collections to more advanced techniques like Threads and Concurrency, Metaprogramming, Network Programming and Distributed Ruby. Each chapter has plenty of code examples and thorough explanations.

I expect my copy to get plenty of used as my programming takes me to unknown or forgotten parts of ruby.

Links:

Fuzzy Match 'All-The-Things'

I started using fuzzy matching when I switched to Sublime Text 2 a few years ago (I currently use Atom, which also has the same feature built-in). The seemingly little improvement increased my productively greatly. It saves a few moments while opening files, but more importantly it prevents context switching. It lets me start working with a file (usually prompted by knowing or wanting to know the contents of it) without needing to think about the location of that file.

In computer science, approximate string matching (often colloquially referred to as fuzzy string searching) is the technique of finding strings that match a pattern approximately

Wikipedia

Such functionality is useful outside of code editors. Thanks to Unix’s modularity, general purpose fuzzy matches can accomplish a lot.

There are a few tools out there, but I found Selecta and Percol to be the more polished o the options. As far as I can tell, they are interchangeable, since they operate on STDIN and STOUT exclusively. I prefer percol on a day to day, because it has better support for the using the keyboard arrows for selection and it has colored output showing the matched portions. It is also full-screen. However, in terms of functionality, both perform equally well.

Changing Projects

My most-common use case for fuzzy matching is changing to project directories. I generally work on a few different projects throughout the day, which reside on different parent directories in my home directories. I created an function cdp that will search common locations using find and pipe the results to the fuzzy matcher for filtering. The output then goes to cd.

1
2
3
4
# .bashrc, .profile, .zshrc or other file sourced by the shel initialization
cdp () {
  cd $(find ~/Development ~/Personal -maxdepth 1 -type d | percol)
}

Fuzz: Fuzzy Match Current Directory Contents

I find myself wanting to find a file in the current directory often. Copying, diffing, working with git, running tests, etc. I created a general-purpose finder that uses find to find all files below the current directory, excluding those in directories starting with .. In addition it can be passed an argument to pre-filter for a string, which I only used on very large projects where find would take a long time to complete and make the fuzzy matching excessively slow.

1
2
3
4
5
# .bashrc, .profile, .zshrc or other file sourced by the shel initialization
fuzz () {
  search_term=$1
  find . -wholename \*$search_term\* -not -path './.*/*' | percol
}

zsh biding for ^S

The culmination of all this, comes by binding ^S on my zsh shell to run fuzz. This allows me to run fuzz while writing arguments to a command already started on the command line and once the fuzzy match is done, returning control to the shell with the argument in place. This allows me to use fuzzy matching on-demand, for any command, across my shell. It has quickly become a tool I reach for throughout the day.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Only for zsh
# ^S for fuzzy matching
# By default, ^S freezes terminal output and ^Q resumes it. Disable that so
# that those keys can be used for other things.
unsetopt flowcontrol
# Run Selecta in the current working directory, appending the selected path, if
# any, to the current command.
function insert-fuzzy-path-in-command-line() {
    local selected_path
    # Print a newline or we'll clobber the old prompt.
    echo
    # Find the path; abort if the user doesn't select anything.
    selected_path=$(fuzz) || return
    # Append the selection to the current command buffer.
    eval 'LBUFFER="$LBUFFER$selected_path"'
    # Redraw the prompt since Selecta has drawn several new lines of text.
    zle reset-prompt
}
# Create the zle widget
zle -N insert-fuzzy-path-in-command-line
# Bind the key to the newly created widget
bindkey "^S" "insert-fuzzy-path-in-command-line"

It is worth noting that most of this ideas where obtained directly from the Selecta README. Thanks Gary Bernhardt!


UPDATE (03/10/2015): A new project was just announced that has another interchangeable fuzzy picker utility, pick. This one is written in C, so it promises to be faster. More importantly, the project shows some more fantastic ideas on where to leverage fuzzy matching.

The REPL: Issue 7 - February 2015

Introducing Discrete Integration

Gustave Dutra at Plataformatec, discusses a concept called Discrete Integration. The process described is very similar to what I use at work at the moment. A sort of dialed-back version of Continuous Integration. It reaps a lot of the benefits of rapid feedback, just not as extreme. Feature branches are worked-on until they are at a stable state before merging into master. Good developer communications is encouraged at all stages.

Require Only What You Require

Janko Marohnić presents a well-thought out argument against requiring all code in gems up-front. His concerns are around what this communicates to other developers. The intention of each file or library required is lost as are the dependencies of each individual class. Finally, it makes it harder to clean-up dependencies once the are no longer used. I intend to adopt this style in the next gem I work on. I have actually done a similar thing in some Rails project, with a smaller scope: For example, if a class uses an external service wrapper, I require it on the top of the class even though it’s already required by bundler, as a notice to other developers on the project.

Programming Is Not A Craft

I previously wrote about my thoughts on the Software Craftsmanship metaphor. My main objection to the metaphor is that it evokes imagery that is not helpful to software development and completely unnecessary. In this article Dan North’s tells us that the risk behind the craftsmanship movement lies in putting software ahead of the benefits it provides. My understanding is that so called ‘craftsmen’ pride themselves in delivering value first, but the article did provoke in my a deep sense that there is a lot of navel-gazing going on. Let’s just focus on professionalism and excellence. Keep calm and code on.

Mark Methods Private When You Don’t Test Them

In his usual clear way Pat Shaughnessy writes about when to mark methods as private. Essentially, methods that have tests are part of what is considered the public API of the object. Untested methods and those that are private are not. Ruby performs the most basically check against calling private methods, that can be easily circumvented by using send. However, marking methods as private is more about communicating to other developers what part is internal to the class and should not be relied upon. This is very much in vein with Sandi Metz take on testing

Experiment: Use RSpec Expectation Syntax

A few months ago, the RSpec team announced the new expectation syntax. In the simplest form, the old way of saying:

1
2
foo.should eq(bar)
foo.should_not eq(bar)

is now:

1
2
expect(foo).to eq(bar)
expect(foo).not_to eq(bar)

Most of my work is on a long-running project with an extensive test suite. It has over 8,000 should statements in it:

1
2
$ ag '\.should' spec | wc -l
    8097

This personal experiment is a simple one: Stop using should. Use expect.

The motivation for the experiment is to not be left behind. The writing is on the wall. Although the RSpec team has not announced the deprecation of the should syntax, it is clear that the prefer the expect syntax and believe this is the way forward.

Methodology

For the last two weeks, I have been writing all new specs exclusively with the expect syntax. At this point, I have made no effort to change all existing uses of should. I have always liked the should syntax for its expressiveness, which I suspected was lacking in expect.

Results

I was pleasantly surprised. At first, I found myself immediately reaching for my trusted should. Pretty quickly expect started to become second nature. I still believe that should is bit more expressive when reading complete lines of code. However, expect does have an advantage: It is usually at the beginning of the line, which makes it obvious which lines are setup for the example and which are the expectations or assertions.

Going Forward

expect is in, should is out for all new specs. There is no immediate intention to convert wholly to expect because the project is large and we can’t immediately move to RSpec 3.x branch anyway (becuause of a conflict with another gem). That will need to come at a later time. In the meantime, we can start converting file by file as we touch them and do the work piecemeal.

2014 RubyConf - San Diego

Better late, than never: Last November I attended RubyConf for the first time. This year it was in sunny San Diego, which I happen to call home.

This was my first time and I was really happy I went. I gather this was the biggest RubyConf yet, with attendance around 900 people. I had a really good time. I returned full of new ideas, which I guess that is the point of going to conferences in the first place.

I have heard often that the best part about Ruby is the community. After attending an event like this, I agree. Don’t get me wrong, I like the language itself and love it’s expressiveness. The community of people that write ruby gems, frameworks, organize conferences and prepare talks is amazing and what really sets Ruby appart from other languages I have used in the past.

The organizers did a great job: The venue and program where great. See you in San Antonio next year!