Today I Learned

9 posts by ryandevilla

Cherry-picking a range of commits in git

Problem

I would like to cherry-pick a range of commits (e.g. an entire branch). For example, I want to cherry-pick the commits f00b4r to f00ba5, where foob4r is the oldest commit on the branch.

Solution

git cherry-pick f00b4r~..f00ba5.

Non-Invasive Monitoring of Socket Traffic

Problem

I would like to diagnose failures to communicate with an external service over a network socket, without making modifications to the code or otherwise disturbing a production-like environment.

Solution

One writes to or reads from a socket by making a request to the kernel (a.k.a syscall). This requires the file descriptor (numerical identifier) of the socket and the message to be sent over the socket, or a buffer that will contain the next message read from the socket.

Using strace (or dtruss on MacOS), one can inspect the stream of syscalls issued to the kernel and the arguments for each syscall. First, find the ID of the process that will be communicating over the socket:

ryan@staging ~ $ ps ax | grep unicorn
99999 ?        Sl     0:00 unicorn worker[0]

Then attach to the process with strace:

ryan@staging ~ $ strace -p 99999
Process 99999 attached
[pid 99999] write(11, "Hello", 6) = 6
[pid 99999] read(11, 0xBAAAAAAD, 64) = -1 EAGAIN (Resource temporarily unavailable)

Here, a Hello message was sent with a write syscall over socket with file descriptor 11, though the read syscall failed as the socket was temporarily blocked.

Unicode Entry on Mac OSX

If you have the code point of a Unicode character, it is possible to enter these characters into (almost) any program on Mac OSX, by first jumping through a few hoops:

  • Open Language & Region.
  • At the bottom right, open Keyboard Preferences...
  • Click the plus sign at the bottom left to add a new Input Source.
  • Under the Others category, select the Unicode Hex Input source.
  • Check the Show Input menu in menu bar option.

You should now see a country flag in your menu bar, which will allow you to switch between different Input Sources (e.g. Canadian English, U.S, Unicode Hex Input). Whenever you want to enter Unicode characters, switch to the Unicode Hex Input source.

Now, you can hold down ⌥ (Option/Alt) and enter your code point to type Unicode characters. For instance, the ⌥ character has code point 2325 and can be entered by holding Option and entering 2325.

iTerm2 Window Arrangements

Motivation

Over the course of development on a project, there are many common jobs that one may run on a daily basis, such as:

  • Starting a Rails app and watching a log tail
  • Running a Zeus server and monitoring its status
  • Monitoring RSpec output
  • Keeping an IRB session open for quick experiments

I like to have a consistent workspace and layout that I can assume is readily available, as opposed to hunting down multiple terminal windows on my desktop. iTerm2 happens to provide a built-in mechanism for preserving workspaces and layouts.

Solution

Once you have all of your iTerm2 panes, windows, and tabs arranged to your liking, you can hit ⌘⇧s (Command-Shift-S) to Save and name your arrangement.

The next time you start iTerm2, you can Restore your saved layout by pressing ⌘⇧r (Command-Shift-R).

Diffing code snippets between large files

Sometimes I like to compare and contrast differences between sections of large files that exhibit textual similarity.

Suppose I want to compare lines 100-200 from FileA.txt with lines 300-400 from FileB.txt. The following can be accomplished from the command line as follows:

diff <(sed -n '100,200p' /path/to/FileA.txt) <(sed -n '300,400p' /path/to/FileB.txt)

You can substitute diff with any program of your choice (try diffuse, meld, or vimdiff).

Inheritance does not affect method visibility

Contrary to visibility conventions in other languages such as Java, Ruby methods defined under a private block in a class definition are still accessible by that class' children:

class Foo
  private

  def private_method!
    p "Hello world!"
  end
end

class Bar < Foo
  def uses_private_method
    private_method!
  end
end

b = Bar.new
b.uses_private_method # => "Hello world!"

This is because the private keyword in Ruby has nothing to do with inheritance; declaring a method as private only adds the restriction that it may not be invoked with an explicit receiver, as illustrated below:

class Quux < Foo
  def explicit_receiver
    self.private_method!
  end

  def implicit_receiver
    private_method!
  end
end

q = Quux.new
q.explicit_receiver # => NoMethodError: private method `private_method!' called for #<Quux:0x007fee689e0ff8>
q.implicit_receiver # => "Hello world!"

Stashing untracked files in Git

Scenario

I have created new files in the process of spiking an implementation, and want to stash them to prevent Untracked files from appearing in git status.

Solution

Use git stash save -u.

Specify Multiple Examples by Line Number to RSpec

I can specify multiple examples as a colon-delimited list of line numbers to RSpec:

ryandv $ rspec my_spec.rb:2:8
Run options: include {:locations=>{"./my_spec.rb"=>[2, 8]}}
..

Finished in 0.00052 seconds (files took 0.08873 seconds to load)
2 examples, 0 failures

Reverse-search in IRB.

You can reverse-search through previously entered statements in IRB by pressing Ctrl-R:

~
 irb
2.1.6 :001  def something_complicated(x,y); x + y; end
 = :something_complicated
2.1.6 :002  quit

~ 10s
 irb
(reverse-i-search)`compli': def something_complicated(x,y); x + y; end

Happy hacking!