Tuesday, December 27, 2011
Exercise 38: Reading Code: Learn Ruby the Hard Way: Practicum
This exercise requires us to go out and find someone else's code and see if we can make sense of what we see. What I found was that, in most cases, there is little in the way of completely self contained projects. Most of the projects that are out there rely on other gems or other elements that have already been developed somewhere else. While this is an effective and contained way to pull in functionality, it can be frustrating to try and find where the actual files are.
I decided to take a look at a project called "shoulda" which is a testing framework along the lines of Cucumber. What I found while going through "shoulda" is that shoulda is a meta project, and that the actual work is being done in two other projects, shoulda-context and shoulda-matchers.
Right now, my goal is to check and see what I can understand from what I am reading, and what I cannot. As I was looking through a number of the files, I found some things that were easy to understand and made sense of the first run, and I found some other things that, while I didn't quite get how they were being implemented, I understood their context and what they were doing. Case in point, there is a "usage" function. It prints out what is not meeting the requirements and then shows a boilerplate text of how the application should be used.
While a lot of the specific implementation details are still fuzzy, I've found that by going through the files themselves and just stepping through the modules and functions as they are defined, I can understand a lot of what the application is doing. Some of the stuff is still over my head (mainly because there's a few areas I've yet to focus on) but much of the details are not so foreign now.
As was made clear in the last exercise, just going through and defining the majority of the keywords, operators and flow control options made a big difference. It has helped me to see that many of the terms that are used in code that I'm unsure of are actually defined someplace else, and usually are not too hard to find once you track down and follow the require statements in key files.
The areas that I am actually still finding myself having more trouble with are the specific methods that are allowed with a given object. the good news is that, in most cases I've seen so far, these methods are generally well explained if their root objects are easy to get to and understand.
Each time I think "yeah, I've got this down", I'm finding that there's still a lot more to learn when I read someone else's git repository (or check out our own projects that we run in our test environment). My own "simple" scripts that I keep track of on my automation environment use a lot of different gems and projects, and I find that many of the statements used in Cucumber, for example, some are specific to RSpec, some use Capybara nomenclature, and some use things that point to technologies and projects I have little understanding of.
On one end, it's helpful in that a lot of the details have already been put together for me, and I just use the steps that make sense and I don't have to do a lot of tweaking. On the other hand, this raises new frustrations, in that if you need to make a change or edit something to work in a different way, you may strike it lucky making a change, but you are not 100% sure that you understand where that change has impact.
For me, certainly, I've found that a change that worked in one instance didn't work so well in another, and I was hard pressed to understand why. This is where being able to track all of the dependencies in a project, and what code and "flavors" of interaction they produce can help a lot.