Ruby Exec/Frank Dependencies

Recently I’ve been working on a little project for Testing with Frank. In using it, I found very early on that the  wait_for_nothing_to_be_animating function has some issues. I detailed it a little in my post about Frank’s Ruby API, but as a refresher, frank mistakenly thinks that the keyboard is always animating. This is a problem that I assume other people have either not tried to deal with, or have dealt with via sleep. To me, that is just not an option, so I modified the Shelly Source.

The modified *.a files, and the fact that I’m used to using package managers and git made me very unhappy the first time I set up a project to use frank.

For anyone that doesn’t know, to set up a project with frank, all you have to do is run  frank setup and then when prompted, tell it which target to frankify. When you do this, it creates a Frank folder with all of the libraries frank needs to link with, an extra folder for any plugins you want, some *.xcconfig files, and a folder where you are expected to put all of your Cucumber tests. You are expected to put this whole folder, with the exception of the folder generated for  frank build artifacts, into your source control system.

I guess this is sort of ok if you’re using SVN, but in Git, if you put a *.a file into your repo, it, and any other versions are there forever, and I really don’t like this. Additionally, if you have multiple targets, it quite possible that you will have developers that never actually need the extra files. I know this can seem like I’m living high and mighty up on my little soap box, but I don’t care.

The solution I came up with was to create my own little pack management tool for the frank dependencies. For the sake of sticking on topic, I’ll go over the theories in here, and then I’ll post my source at the end. If you’re interested, you can make it an exercise of your own to figure out how it works.

Executing Code From a File

I know this probably seems odd, but hear me out. If you’ve ever looked at a Gemspec, you’ll know that they usually look something like this (example from RubyGems Documentation)

Have you ever wondered how it is that you can write a Gemspec, in real Ruby code, and somehow it gets used? Normally when you do a require, a file will be read and executed, but in the case of a Gemspec, how do you get the return value? require will only return true or false, and in the Gemspec you aren’t setting any global variables.

The magic happens in Ruby’s eval method. Eval will evaluate a string as Ruby code and return the value. For example:

This may seem a little useless at first because couldn’t we just call double directly? Well remember, the intention is to have some code in 1 file, and evaluate it in another so that we don’t have to rely on any more convention that needed to have inter file communication.

Using eval, we can read in a whole file, then execute the code in it to save off our variable

 C# like Object Initializer Syntax

Several times I’ve seen this fancy syntax while looking at Ruby code

It’s very similar to C#’s object initializer syntax, but unfortunately, you don’t get this for free in Ruby. It’s pretty easy to get though. All you have to do is add this to your initialize method

There’s more information for yield and instance_eval over here

My Frank Downloader

Without further tangents, this is what I came up with for downloading the Frank linked libraries. I know that it’s not pretty, but it also only took me about 2 hours to do from start to finish.


Leave a Comment

Your email address will not be published. Required fields are marked *