Hardscrabble 🍫

By Max Jacobson

how to log all input in your pry rails console

14 Oct 2015

Many Rubyists use and love the pry gem for adding breakpoints to their programs and inspecting objects. Super useful. Some others use the pry-rails gem to use the pry REPL in place of irb for the rails console.

Let’s say you want to log all of the activity that occurs in your rails console. This could be a nice security thing. Maybe you’re just nostalgic for old times.

Pry has something called an “input object”, which you can override in your configuration. The object’s responsibility is to feed ruby code to Pry, line by line. By default, it uses the Readline module. I don’t know a ton about readline, but I gather that it’s wrapping some standard unix program, which means it sort of feels natural. For example, you can input Control+l and it will clear the screen; gets.chomp doesn’t do that kind of thing.

So, Readline is great. We want to use it. We just kind of want to wrap it. SO let’s see what that looks like.

First: where do we actually put our configuration?

You can put a .pryrc file in the root of your project. You can even put Ruby code in that file. I think that’s the official way to do it. But I don’t know… it doesn’t get syntax highlighting because it doesn’t have a .rb file extension… I put my configuration in a Rails initializer named config/initializers/pry.rb, and that works fine too.

class LoggingReadline
  delegate :completion_proc, :completion_proc=, to: Readline

  def readline(prompt)
    Readline.readline(prompt).tap do |user_input|
      logger.info(user_input)
    end
  end

  private

  def logger
    @logger ||= Logger.new('log/console.log')
  end
end

Pry.config.input = LoggingReadline.new

The important thing for custom input objects is that they implement the readline method. The method takes in a string that holds the current user prompt, and it is expected to return a string that holds the next line of Ruby code for Pry to evaluate.

If pry is a REPL (read evaluate print loop), the custom input object assumes the responsibility of the first letter, and thats’ it.

It doesn’t strictly need to ask the user for input. It could just return some nonsense.

But, this one does. We can summarize what it does as: ask the dev for a line of input, but first log it to a file before returning it to pry for EPL-ing.

There’s one line that’s kind of strange:

delegate :completion_proc, :completion_proc=, to: Readline

What’s that about?

Well, I’ve learned, it’s just kind of a necessary thing to make sure your custom input object seamlessly behaves like the default pry input behavior. Let me explain.

Readline, by default, has some strategy for tab completing when you start to write something, and then press tab. That strategy is a proc object. The default one has something to do with irb I guess?

$ irb
>> Readline.completion_proc
=> #<Proc:0xb9964ce0@/home/max/.rubies/2.2.3/lib/ruby/2.2.0/irb/completion.rb:37>

But! When starting pry, it has a different completion proc!

$ pry
[1] pry(main)> Readline.completion_proc
=> #<Proc:0xb8a0c25c@/home/max/.gem/ruby/2.2.3/gems/pry-0.10.2/lib/pry/repl.rb:177>

But when you provide a custom input object, pry doesn’t replace the completion proc on readline because you seem not to even be using it, so why bother? But in this case we totally are using it, we’re just wrapping it.

At first, I thought this was a bug with Pry, and I opened an issue to complain about it, but while writing this blog post I realized that it’s kind of not a bug, and this delegation approach is probably fine.

fake tools

11 Oct 2015

Last week, Flatiron School launched a new online learning program called “Learn Verified”. The launch was accompanied by a letter from the founders, Avi and Adam. This section jumped out to me:

Real Tools

You can’t learn real skills with fake tools. As much as you can learn in a simulation, you can’t become a competent surgeon without picking up a scalpel or pilot without stepping into an airplane. Yet, online learning platforms today teach people using in-browser, simulated coding tools (often referred to as REPLs) and multiple choice quizzes which, while helpful, can never bring a student to the level of competency required of a professional software engineer.

Learn requires students to use the same tools and workflows that professional software engineers use on the job. From the start, students work in their terminals using git-based workflows. They’re taught to master the craft using the tools of the trade.

On the most recent episode of metaphor loop, we talked about the different styles of learning. One of them was kinesthetic learning, which we can say is like “hands on” learning. I hadn’t heard the term until Vaidehi told me about it and I realized I identified with it. I think kinesthetic learners are the same ones who will identify with Learn Verified’s emphasis on using “real tools”, because they’ll get to get their hands on the material they’re learning in a more direct, free-to-explore way. That market of learners has been underserved by the existing solutions, and I wonder if Flatiron will be able to pull off an online learning environment just for them.

I do kind of chafe at the idea that “you can’t learn real skills with fake tools”, though. It feels like a pretty inflammatory position to take. I’m reminded of Lost’s great “Don’t tell me what I can’t do!” catchphrase. Aren’t some people different from other people? And not to be all metaphysical here, but aren’t all tools kind of fake tools? Where do you draw the line? idk.

participate in society

03 Oct 2015

If there’s one piece of advice I feel comfortable giving, it’s this: participate in society. Find it in your introverted self to join in.

When you hear vaguely that you ought to be using zsh instead of bash, but when you try it you’re not sure why it’s better, stick with it. When you hear that oh-my-zsh is a good way to manage your zsh configuration and you think the name is dumb and don’t want to use it, get over yourself, because months later you’ll find yourself desperately googling to see if anyone else is using zsh in tmux on el capitan and experiencing a weird behavior where option-backspace isn’t working (it’s supposed to delete backwards a full word), but only when in tmux, and you can’t really find anything, just throw out your zsh configuration and use the thing that people use. You won’t regret it.

Anyway, that’s just my one piece of advice.