Ylan Segal

List Open Files With Lsof

In the UNIX paradigm, everything is a file system. So, it makes sense that there is a utility to work with open files.

A common use case is to try to eject a mounted drive or clear the trash and get a warning about a locked file. What process has this file or folder open?

1
2
3
$ lsof /Volumes/Personal/blog/source/_posts
COMMAND     PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
Sublime   13472 ylansegal  cwd    DIR   14,7      442 6072 /Volumes/Personal/blog/source/_posts

Since everything is a file, it works just as well with ports:

1
2
3
$ lsof -i :4000
COMMAND   PID      USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    20740 ylansegal    7u  IPv4 0xffffff80158d6de0      0t0  TCP *:terabase (LISTEN)

Or you can check the files for a specific program:

1
2
3
4
5
6
7
8
9
10
11
$  lsof -p 21286
COMMAND   PID      USER   FD     TYPE DEVICE  SIZE/OFF    NODE NAME
tail    21286 ylansegal  cwd      DIR   14,7       850      28 /Volumes/Personal/blog
tail    21286 ylansegal  txt      REG   14,4     57488    9770 /usr/bin/tail
tail    21286 ylansegal  txt      REG   14,4    599280    8989 /usr/lib/dyld
tail    21286 ylansegal  txt      REG   14,4 299110400 3283993 /private/var/db/dyld/dyld_shared_cache_x86_64
tail    21286 ylansegal    0u     CHR   16,1  0t238994     723 /dev/ttys001
tail    21286 ylansegal    1u     CHR   16,1  0t238994     723 /dev/ttys001
tail    21286 ylansegal    2u     CHR   16,1  0t238994     723 /dev/ttys001
tail    21286 ylansegal    3r     REG   14,7      1450     240 /Volumes/Personal/blog/Gemfile.lock
tail    21286 ylansegal    4u  KQUEUE                          count=0, state=0x2

lsof supports many, many options, read the man pages for more information.

Book Review: Practical Object-Oriented Design in Ruby - Sandi Metz

If you call yourself a ruby programmer, you should read this book.

Sandi Metz has done a great job explaining how to write maintainable applications, in a way that is accessible to programmers at any skill level. Her book is concise (less than 250 pages, including the index), but jam-packed with great nuggets of practical advice and coding techniques that you can start applying immediately in your projects. Her style is easy to read, with many code examples that show you the evolution of code, as an application changes and is refactored.

Among the techniques discussed:

  • Use dependency injection to avoid coupling between objects. (Makes them easier to test too)
  • To write great APIs, focus on the messages being sent between objects. (She shows why you would actually want to use a UML diagram)
  • By creating role tests and applying them to test doubles, you can avoid the ‘leaving the dream’ problem, where stubs in tests obscure the fact that objects interfaces have changed.

Links: Publisher Site, Amazon.com

StandardError Casts Message to String in Ruby 1.9

When passing a message to StandardError in ruby 1.8, it will keep that object intact. Ruby 1.9 will convert to a String. Spent more time than I wanted to chasing this down.

In ruby 1.8.7:

1
2
3
4
5
6
>> RUBY_VERSION
=> "1.8.7"
>> err = StandardError.new(Object.new)
=> #<StandardError: #<StandardError:0x78952527>>
>> err.message.class
=> Object

In ruby 1.9.3:

1
2
3
4
5
6
>> RUBY_VERSION
=> "1.9.3"
>> err = StandardError.new(Object.new)
=> #<StandardError: #<Object:0x456c5f50>>
>> err.message.class
=> String

Run Changed Specs

I usually create a branch while working on a feature or bug. I found it helpful to add the following script to my path:

1
2
3
#! /bin/bash

git diff --name-only master..HEAD | grep 'spec.rb' | xargs rspec

It’s quick and dirty, but effective. It asks git for a list of filenames that have changed in the current branch, filters them to find specs and runs them with rspec.