Interestings
holepicker
http://psionides.eu/2013/02/18/pick-holes-in-your-gemfiles/
Find gems with vulnerabilities
Explore Blog posts about everything we are up to, Tech Talk videos covering a huge range of timely topics and Event listings to keep you current on happenings at the Labs.
http://psionides.eu/2013/02/18/pick-holes-in-your-gemfiles/
Find gems with vulnerabilities
I’ve been spending an awful lot of time lately deploying rails applications using chef server. I’ll be blogging some of the more interesting ways we’re using chef server. One of the most useful features of chef server is search. This allows you to write recipes that reference nodes in your stack that match particular roles. In this post I’ll describe how we use search to generate a rails database.yml. This becomes particularly useful when creating and deploying the same rails application to multiple stacks.
First of all we added a simple file read in our database.yml file in place of the connection details.
<% if File.exist?('/opt/apps/fbfcats/shared/database_include.yml') %>
<%= File.read('/opt/apps/fbfcats/shared/database_include.yml') %>
<% end %>
In our chef project we have a recipe that searches for the database server node and writes out the database_include.yml file using a template resource.
master = search(:node, "role:db_master AND chef_environment:#{node.chef_environment}").first
template "/opt/apps/ms/#{app_name}/shared/database_include.yml" do
owner "gemini"
group "gemini"
source "database_include.yml.erb"
mode "0600"
variables(:hostname => master,
:database_name => "fbfcats" + "_" + node[:rails_env],
:user => 'fbfcats',
:password => 'mittens',
:rails_env => node[:rails_env])
end
Finally the template.
<%= @rails_env %>:
host: <%= @hostname %>
adapter: mysql2
encoding: utf8
reconnect: false
database: <%= @database_name %>
pool: 5
username: <%= @user %>
password: <%= @password %>
We built an(other) object factory module for our current project and it looks a lot like all the others:
We ran into a problem where we were running `gem build` on identical input files and the built gems had different checksums; that is to say, if you run `gem build` twice in a row, the resulting `foobar.gem` files will not be identical.
A .gem file is actually a tar file (not compressed) containing two gzipped files (manifest.gz and data.tar.gz). What’s happening, as far as we can tell, is that gzipping a file embeds a timestamp somewhere in the file — here’s a gist of a Bash session that demonstrates just this idea:
Apparently gzip on its own can exclude the timestamp, but that option doesn’t seem to be exposed through tar.
So how do you build identical gems from the same input? As far as we could discover, that is not supported through any `gem` commands. To normalize a gem, you would have to untar the .gem file and then decompress the files inside; then you can do a full comparison of those contents against another .gem file that went through the same process.
The Lobot project is recruiting team members. Mostly that means that when scheduling permits, you’ll work on Lobot as a project. Contact Ken (the new PM), or Davis.
I have a module that creates methods dynamically, but I want Command-B to work for those methods.
before_save and after_save will happily take an on: :create option, and then completely ignore it. before_validation takes an on: :create option, and actually works, which is why it feels natural to put on: :create after a before or after save.
The right answer, apparently, is to use before_create or after_create.
We recently added the resque-pool gem which does alias_method on the resque worker shutdown? method to look at the pid of the process being shutdown. On Heroku this always evaluates to true.
Takeaway message don’t add resque-pool gem to your gemfile for an heroku application.
Weekly email of curated links from hacker news. Recommended by Rajan.
Ruby Science: https://learn.thoughtbot.com/products/13-ruby-science
This is the second part in a series I’m writing about lessons that can be learned from functional programming. Find the first part here.
Object Oriented Programming (OOP) as an idea has been oversold. The most commonly used languages in use today are designed around the idea of OOP. Extremist languages like Java force you to think of everything in terms of objects. But is Object Orientation (OO) a good idea? Does it have problems? Is it the right tool for everything? Let’s explore some of these questions in a slightly tongue in cheek and cathartic rant.
The object-oriented model makes it easy to build up programs by accretion. What this often means, in practice, is that it provides a structured way to write spaghetti code. — Paul Graham
Procedural programming languages are designed around the idea of enumerating the steps required to complete a task. OOP languages are the same in that they are imperative – they are still essentially about giving the computer a sequence of commands to execute. What OOP introduces are abstractions that attempt to improve code sharing and security. In many ways it is still essentially procedural code.
Declarative languages on the other hand are about describing computation. While a a declarative language necessarily maps down to imperative code, the resulting code often reveals less incidental complexity and can sometimes be much more easily parallelized.
The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. — Joe Armstrong
State is not your friend, state is your enemy. Changes to state make programs harder to reason about, harder to test and harder to debug. Stateful programs are harder to parallelize, and this is important in a world moving towards more units, more cores and more work. OOP languages encourage mutability, non determinism and complexity.
As someone who was initially hostile to the idea that state is the root of all problems, I initially greeted this idea with skepticism. Mutating state is so easy and fundamental in OOP that you often overlook how often it happens. If you’re invoking a method on an object that’s not a getter, you’re probably mutating state.
Java is the most distressing thing to happen to computing since MS-DOS. — Alan Kay
The typical college introduction to OOP starts with a gentle introduction to objects as metaphors for real world concepts. Very few real world OOP programs even consist entirely of nouns, they’re filled with verbs masquerading as nouns: strategies, factories and commands. Software as a mechanism for directing a computer to do work is primarily concerned with verbs.
OOP programs that exhibit low coupling, cohesion and good reusability sometimes feel like nebulous constellations, with hundreds of tiny objects all interacting with each other. Sacrificing readability for changeability. Many of OOP best practices are in fact encouraged by functional programming languages.
Object-oriented programming is an exceptionally bad idea which could only have originated in California — Edsger W. Dijkstra
Inheritance is one of the primary mechanisms for sharing code in an an OO language. But this idea is so problematic that even the keenest advocates of OO discourage this pattern. Inheritance forces you to define the taxonomy and structure of your application in advance, with all it’s connections and intricacies. This structure is resistant to change which is one of the primary problems software developers face every day. It also fails to model some pretty fundamental concepts.
This is far from an exhaustive list of the criticisms leveled at OOP. While I believe the problems with OOP are extensive, I do think it is a valuable mechanism for developing software. But is certainly not the only one. The biggest problem in my mind is thus:
When people overcome the significant hurdle of fully appreciating OOP, they tend to apply it to every problem. OOP becomes the solution, and every problem looks like a nail.
There’s got to be a better way…
Has anyone tried/prefer any particular iOS analytics tools? We’re looking at Google Analytics, Flurry, and Mixpanel. Per-user drill downs would be nice and all features we need are supported by all three (custom events with extra data and session tracking).
We’ve got a resque worker on Heroku that dies instantly without any error. When we created one in a rails console it looked as though it was receiving a shutdown signal.
Pivotal Labs is a sponsor of LA Ruby Conference 2013 – http://www.larubyconf.com/. Come see our speakers: Fiona Tay, Robbie Clutton & Matt Parker.
Do us all a solid and remove those ghost devices from your bluetooth settings pane. This will make it easier for others to pair them up with a new workstation.
Do you use Sublime Text? Would you like to see a git line change indicator alongside your files?
https://github.com/jisaacks/GitGutter
Bonus: there’s a vim version! https://github.com/tpope/vim-fugitive
Twitter have release a js plugin for typeaheads:
http://twitter.github.com/bootstrap/javascript.html#typeahead
Come take part in the the special new extended Pair Exchange event on Saturday from 12:30 – 5:30.
Lately I’ve been thinking about the risks associated with:
I’ve identified the key areas of risk as narrative and permalinks.
The narrative of your site/app can break in subtle and unexpected ways. It is difficult to guard against side-effects upon the narrative. This makes changes to domain terms high-risk. Specifically, a developer focused on the code can easily miss these side effects.
Here’s an obvious, and well guarded story:
Given I am a user When I visit the user's profile Then I see their latest activity
That one’s simple, if you move the latest activity to a sub-nav, this story will break (that’s a good thing). In this case, you could ask the product owner, “In the past, having a user’s activity visible on their profile page was desirable. Are you sure you want to lose that?”.
However not all narrative is this cut and dry. Consider this story:
As a user When I visit a member's profile I can see a list of pages the member is interested in.
Then, along comes a new unit of work, “Rename all pages to interests”. This seems reasonable, and so you finish the story. The test for the ‘pages’ the member is interested in continues to work, however the member profile ought to lose any reference to ‘pages’. The new domain term ‘interests’ should be used instead.
Now your tests are using misleading or confusing language. You need to update all your stories to use the new term. This can get onerous quickly, but it’s vital for consistency.
I’m yet to find a satisfying technique for mitigating this risk. It’s hard enough keeping the modelling clear of inconsistencies.
This same change to narrative also affects ‘curators’ of ‘pages’. They no longer curate ‘pages’, they now provide ‘interests’. Do we want the curators to go through this mental hurdle, or the strangeness of ‘managing an interest’ versus ‘my interests’? Suddenly a curator has a list of ‘interests which they maintain’ and a list of things they are ‘interested in’.
The best way to mitigate the ‘broken narrative’ risk is to stay strong on short, testable stories. Fast turnaround between development and acceptance is also valuable. The fast feedback cycle is less overwhelming for both developer and product. The chance to think about risks is stronger when the story is as uncomplicated as possible.
The risk of broken narrative is just another reason to avoid this internal desire to take ‘big bites’.
Permalinks and long lasting links, are any URLs for which permanence matters. E.g., the permalink to an article on your blog from some outside source. The risk of broken permalinks can be readily mitigated in your intrgration tests. To achieve this, you need to make sure that product is thinking actively about permalinking. Impart to the product owner that permalinks must be (as much as is possible) explicitly called out in stories.
Here is an example.
A story in your backlog calls for content that must be available in a permalink. You write a scenario like this:
Given I am a visitor And there is an article When I click on a permalink for the article Then I should see the article
The important term in this story is ‘permalink’ – whenever a step definition calls for a permalink, it needs to use a constructed link:
visit ('/articles/#(article.slug}')Do not use Rail’s (or your framework of choice) magic:
visit(article_url(article)) # won't capture intent
This way, if the permalink goes away, the test fails, and the intent is clearly captured.
To complicate matters, a moderately complex site usually has a swathe of references to the content you are about to move/refactor. The term is often used in abundance, E.g. ‘Post’ or ‘Job’ or ‘Activity’. The page might be accessed from several places, E.g. messages are available from the ‘User -> Messages’ nav item, the ‘”My Favorite Lolcats” group messages’ page etc..