vim commands and piping

You may know that you can execute commands from inside of vim, with a vim command:

:! ruby do.rb

which will execute that code, and then – upon hitting enter, return you to your workspace.

Another nice one, is you can execute the exact same command with:

:!!

I use those a lot, but I just learned you can send the current buffer via a pipe (even if unsaved) into a command like this:

:w !sort

Pretty nifty, huh?

Vundle for Vim

I’ve spent years customizing my vim configuration. My original configuration came from my friend Mat Brown, and from there I started making changes. A while back, I started sharing my dotfiles on GitHub for ZSH, vim, tmux and irssi.

One underlying annoyance was that every time I added a new vim extension, my ~/.vim directory would get even more wooly, even more out of control. I’d just be dumping files into these directories, and hoping everything kept working — luckily, it always did :)

Recently, I’m really into vundle, and every file in my vim configuration (except for ~/.vimrc) has since gone away. Vundle handles all of it.

Vundle is essentially a package manager for vim, which allows you to pull in vim files from git locations. It keeps installation easy, and updates painless. You just specify things like:


Bundle ‘ZoomWin’ # https://github.com/vim-scripts/ZoomWin
Bundle ‘vim-ruby/vim-ruby’ # https://github.com/vim-ruby/vim-ruby
Bundle ‘https://github.com/some/full-location’

and then you can :BundleInstall to get going. Definitely check it out if this is (/ has been) a problem for you: vundle on github

Custom RSpec Contexts

Sometimes it can be useful to have custom RSpec contexts. In a recent project, a library which matches Strings to pick up dates mentioned in the string, I really wanted to write tests like:


thoughts_on Date.today do
think ‘Tomorrow at noon’, Date.tomorrow
think ‘Today is the best’, Date.today
# … a bunch more of the same
end

.. no writing the same if‘s over and over again

Furthermore, I wanted to do it in a reusable way, so that I wouldn’t need to be defining methods inside of these blocks. I wanted the tests to just get across the data that was needed (in this case, the date in question, and the before & after state for a transformation).

What I ended up learning, is that in RSpec, context and describe return their evaluation objects. So, I were a Module and a def from what I wanted:


module ThoughtMethods
attr_accessor :pickup_parser
def think(phrase, reference)
parser = pickup_parser
it “should see #{phrase} as #{reference}” do
parser.locate(phrase).should == reference
end
end
end

def thoughts_on(today, &block)
example_class = describe “on #{today}”
example_class.extend ThoughtMethods
example_class.pickup_parser = Pickup::Parser.new(today)
example_class.class_eval &block
end

It’s nice because you still get all of the same output & separation, with none of the awkward fluff.

Ruby – local variables are undefined

I’ve blogged about this in the past, but I’m bringing it back here because I think it’s fascinating:


coolvar = 42 if false
coolvar # nil

I had seen someone bring up an interesting point, that this seemed natural to them. It was because they had read the above statement as:


temp = 42 if false
coolvar = temp

and then it would only make sense that coolvar have a value. That doesn’t jive with me though, and it shouldn’t jive with you. That would mess up precedence, treating if, more like the precedence of rescue.

Just to demonstrate that isn’t the case, let’s go for another example:


if false
coolvar
end
coolvar # NameError

Uh-oh!!! Now we’re in trouble, you say. We just parsed some code that included a variable and even after parsing it, the variable was still undefined. The precedence is clear here, and the behavior isn’t happening.

Thing is – it’s all about Ruby trying to figure out what coolvar is. In fact, let’s go even further – in Ruby, all undefined local variables are nil. When you type coolvar, Ruby just can’t tell if coolvar is a method or a local variable. So you get a NameError. If you do something that demonstrates to Ruby that it’s a local variable – then when it gets parsed, you can access it and it’s value will be nil. Check it out:


if false
coolvar = ‘yup’
end
coolvar # nil

Hope this helps clear up things!

Ruby: def def

Sometimes some Ruby programmers that want to give me a heart attack write code like this:


class Thing
def run
def loop_thing(i)
puts i
end
10.times { loop_thing(i) }
end
end

That’s a really cool nested function you made there! Only one problem before you go — RUBY DOESN’T HAVE NESTED FUNCTIONS:


thing = Thing.new
thing.run # 0..9
thing.loop_thing(31337) # 31337, no

As we see here — in addition to being able to use define_method, you can actually run def inside of a method body.


Cover your eyes if you don’t want to see the scary thing


class Array
def stop_the_mapping!
def map
raise ‘But you told me to stop ;(‘
end
end
end

arr = [1, 2, 3]
arr.map { |x| x + 1 } # [2, 3, 4]
arr.stop_the_mapping!
arr.map { |x| x + 1 } #