hardscrabble 🍫

By Max Jacobson

Psst. Check out my RubyConf 2017 talk, There are no rules in Ruby.

blog posts

whoa, ruby's alias is weirder than I realized

23 Jun 2014

Just saw some ruby code using the alias method, and did a quick and routine google to find some examples of how it works, especially as compared to the alias_method method.

This blog post and some others recommend to use alias_method over alias and I’m going to agree, but for different reason: calling alias looks weird to me.

This looks perfectly normal to me:

class Whatever
  def whatever
    "whatever"
  end

  alias_method :something, :whatever
end

Whatever.new.whatever #=> "whatever"
Whatever.new.something #=> "whatever"

alias_method is a method that takes two arguments and they’re separated by commas. Under the hood I don’t know what it’s doing but that’s never stopped me from calling a method, and I know how to call a method.

This looks goofy to me:

class Whatever
  def whatever
    "whatever"
  end
  alias :something :whatever
end
Whatever.new.whatever #=> "whatever"
Whatever.new.something #=> "whatever"

What even is that? It looks like we’re calling a method, but the arguments aren’t comma-separated… it feels weird.

I guess this probably isn’t a great reason to prefer one programming technique over another, but for me it’s harder to understand and therefore remember, and what I really like about Ruby is that it’s simple – almost everything is an object or a method, which follow some set of learnable rules.

alias_method is a method; alias is a keyword, like def or class and it can be even syntactically weirder:

class LowfatKefir
  def probiotic?
    true
  end
  alias tasty? probiotic?
end
LowfatKefir.new.tasty? #=> true

Not only do you not need to comma-separate the “arguments” to alias, but they don’t have to be symbols either which feels like another violation of my understanding of how this language works, which is that we use symbols when we want to reference methods without invoking them, because referencing the method always invokes it.

selecta

05 May 2014

One of my favorite things about my vim setup is the way I open files. For a little while I used ctrlp and then I switched to Gary Bernhardt’s selecta script.

selecta is cool in part because of how it’s designed to be more than a vim plugin, although that’s mainly what I use it for. The readme gives a few examples of how else it could be used and other people come up with weirder stuff.

Also cool is the means of distribution. Recently someone added it as a homebrew formula, making it easy to install and keep it up-to-date on a Mac, but until then, the recommended move was to download a raw ruby script, make it executable, and put it on your PATH, and then I guess hope to remember to update it occasionally. If you want to use it in vim, you can copy and paste a vimscript function from the readme into your vimrc.

Here’s the code from the readme:

" Run a given vim command on the results of fuzzy selecting from a given shell
" command. See usage below.
function! SelectaCommand(choice_command, selecta_args, vim_command)
  try
    silent let selection = system(a:choice_command . " | selecta " . a:selecta_args)
  catch /Vim:Interrupt/
    " Swallow the ^C so that the redraw below happens; otherwise there will be
    " leftovers from selecta on the screen
    redraw!
    return
  endtry
  redraw!
  exec a:vim_command . " " . selection
endfunction

" Find all files in all non-dot directories starting in the working directory.
" Fuzzy select one of those. Open the selected file with :e.
nnoremap <leader>f :call SelectaCommand("find * -type f", "", ":e")<cr>

I made one change, which was to use ctrl+p instead of leader+f, because I’d trained my fingers on ctrl+p and didn’t have the reserves of peace & discipline to consider changing. Other than that I left it as-is, until today.

I wanted to edit my .gitignore file, and noticed that it wasn’t opening. Not a big deal, I wrote :e .gitignore and survived.

The comment says it opens all files in all non-dot directories. It’s kind of true but not exactly, as it ignores dotfiles regardless of their location. I definitely want it to ignore files in dot directories (.git and .sass-cache come to mind), but I don’t want it to ignore most dotfiles.

selecta works like this: you pipe some list of information into it, it breaks it apart, lets you select one line from the list, and then pipes that selection out to the next command. This vim plugin runs the bash command find * -type f, which prints the list of non-dot files (-type f excludes directories, * excludes dots) and then pipes it to the vim edit command :e.

Since setting this up months ago I’ve learned and used the find command a few times but had no idea it was powering my fuzzy opener thing! Something opaque opened up a little. So I edited that last part like this:

" Find all files and all non-dot directories
" starting in the working directory
" and edit the chosen thing
nnoremap <c-p> :call SelectaCommand("find . -not -path './.*/*'", "", ":e")<cr>

The main changes:

  • dotfiles now show up, so I have easier access to files like .gitignore and .travis.yml
  • directories now show up, so I can jump directly to specific directories in netrw
  • now there’s a leading ./ in the list of options because find * and find . have a different output?

I made a before and after gif.

I think I like this! But actually what if it sorted the files by last modified date?