-
Hey man! Just RELAX!
-
David Heinemeier Hansson is a cool dude. He recently got his green card, so I asked him a few questions about the process and received this considered response.
For someone who many believe to be opinionated and some have even said arrogant (incidentally the reasons people say these things about him are why I like him), I find him to be a thoroughly pleasant chap.
-
Rake Stats Isn’t Very Smart
I noticed something at work today. rake stats is dumb when it reports test LOC. This is something to bear in mind when evaluating test coverage mertics, as good test coverage is one thing indicative of the code base.
If you’re anything like me you like to deploy a little metaprogramming to make your tests as DRY as possible. So you might have something like this:
%w[first_name last_name title address postcode email website estate business_type].each do |attribute| it "should not be valid without #{attribute}" do @contact.send "#{attribute}=", nil @contact.should_not be_valid @contact.errors_on(attribute).should include "can't be blank" @contact.send "#{attribute}=", @valid_attributes[attribute] @contact.should be_valid end endThis code generates an expectation for each member of the array object. rake stats will see this as nine LOC, but if you were to do it the long way and explicitly write out all of your expectations, it would count for sixty-three LOC, nine times difference. After a few cases of this, your test coverage stats are going to be distorted and worth less and less.
It’s a bad idea to rely on rake stats to indicate code coverage quality, but this is another reason to give it less weight.
-
Model Layer Attribute Level Access Control
I have this interesting problem at work on this web app. The requirements mandate super fine-grained access control on model objects. It’s not enough to restrict access to CRUD actions, my boss wants different roles to be able to access specific attributes and not others. i.e. normal users can access name but not salary etc.
I came up with a DSL for this. This is what it looks like:
let :admin, :update => :everything, :see => :everything let :users, :update => [:name, :telephone_number, :email], :see => :everything let :guests, :update => :nothing, :see => [:name, :department]
I’ll see if I can get my boss’ permission for me to open source if they’re is demand. Is there?
-
Project Euler in Ruby: Problem #3
Problem
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?
Solution
require 'mathn' class Integer def largest_prime_factor number = self prime = Prime.new divisor = prime.succ while divisor < number number /= divisor if number % divisor == 0 divisor = prime.succ end divisor end end puts 600851475143.largest_prime_factorIn a real application I wouldn’t monkey patch a core class for something such as this, but for this example the OO style makes more sense to me, readability wise to me than a functional solution.
-
Haml & Sass: Pointless abstraction?
I remain unconvinced on the utility of Haml and Sass. I definitely am convinced it’s not commensurate with the airtime they get online and in dev circles.
- Hand coding semantic, well-formed HTML is so trivial every professional developer should be able to do it. It’s not uncommon to have 10+ years HTML experience. People have literally grown up with it.
- Textmate HTML bundle tab triggers and tag autoclosing completely negate the marginal benefit of Haml’s brevity.
- The utility of hand coding CSS in CSSEdit 2 and seeing instant changes in the WebKit preview window > > > > anything that Sass can offer.
I don’t see the point of Haml at all. One has to think of a document’s structure in HTML in order to write it in Haml and then have it parsed back into HTML! WTF?! Even as a Rubyist myself, I have to say that to advocate, let alone proselytize such an approach (as a very vocal minority online do) smacks of pure zealotry.
I think Sass is good for software engineers. So if you’re a coder that wants to write your CSS in a very concise DRY style, go ahead and use it. Just expect your interface to look like it was created by an engineer and not a designer i.e. ugly, As one is less inclined to tweak to perfection if the browser has to be manually refreshed, instead of CSSEdit 2’s instant visual feedback. I can’t see how Sass would make it faster for designers to create beautiful interfaces stepping away from CSSEdit.
I can only see Sass being a speed hump.
Your thoughts?
-
Project Euler in Ruby: Problem #2
Problem
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
Find the sum of all the even-valued terms in the sequence which do not exceed four million.
Solution
class Fibonacci class << self def upto(max_number) # Initial terms fib = [1,2] loop do # Calculate next term t = fib[-1] + fib[-2] # If next term is less than max_number, append to array and repeat, else break loop t < max_number ? fib << t : break end fib end end end # Add even terms together puts Fibonacci.upto(4_000_000).select { |i| i % 2 == 0 }.reduce :+Returns: 4613732
-
Project Euler in Ruby: Problem #1
What is Project Euler?
Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.
The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.Problem 1
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
irb(main):001:0> (0..999).select { |i| i % 3 == 0 || i % 5 == 0 }.reduce :+ => 233168Bada-bing, bada-boom
Explanation
(0..999) is every a Range object containing every natural number under 1000. As it is an Enumerable object…
irb(main):002:0> Range.included_modules => [Enumerable, Kernel]
It responds to select. Select takes a block of code, and returns each element of the enumerable object in a new array when the block evaluates as true. Our block simply asks “is there no remainder when we divide this integer by 3 or 5?” So that is how we extract the numbers that are multiples of 3 or 5.
Calling reduce :+ is equivalent to calling inject and adding the block variable to the memo block variable. That is how we find the sum of those numbers.
-
Ruby 1.9 broke your ish…
Ruby 1.9 has been here for a minute now. If you’re not already using it in production, get ready to because Rails, that opinionated little bugger, really wants you to use it with 3.0
I’m sure you have seen this pattern for extending objects with your own functionality before:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.send :include, IncredibleFunctionalitySlow down fast lane
irb(main):001:0> Module.private_method_defined? :include
=> trueThis will blow up in your face with Ruby 1.9.
includeis a private method of Module and you can no longer usesendto externally call private methods on an object in 1.9.Great. So what are our options?
Open the class:
class ActiveRecord::Base def wozers # Your insanely great code here… end endYuck. Or slightly better:
module IncredibleFunctionality def wozers # Your insanely great code here… end end class ActiveRecord::Base include IncredibleFunctionality endTo me this is insanely horrible. There might be nothing wrong with this, but this just smells to me, from an aesthetic point at the very least. If it could be done in one line AND in a readble, sensible way before, that’s the way I want to do it now too.
HACK AWAY:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.__send! :include, IncredibleFunctionalityYou can continue to use send to call private methods using
__send!Although for me, it’s anathema to continue something that the Ruby maintainers thought badly enough of to change the API.Also worth mentioning that
__send!is new for 1.9. so this will not work on the 1.8 branch, which makes this method kind of useless if you’re hoping that a lot of people might use your code.class_eval:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.class_eval { include IncredibleFunctionality }Sets the context of self in the block to the receiver. Allows us to call include with the implicit receiver being that of the object we wish to extend.
WIN!
These are the ways I’ve come up with to work around this issue. What are yours?
-
Been playing with Ruby 1.9.1, Rails 3.0pre, and MongoDB and it looks good. I can’t wait for MongoDB to really mature, I feel like Indiana Jones going through this source code, uncharted business. On a related note, MongoMapper uses a mixin pattern rather than the inheritance pattern I moaned about ActiveRecord using. I feel vindicated! LOL…
-
Hunger Strikes!
Mad hungry. Time to take a break from coding and hit Nando’s with a new friend?
irb(main):001:0> s = "om"; 4.times { s << "nom" }; s << "!"
=> "omnomnomnomnom!" -
Ruby Idioms & Shortcuts: The Splat Operator
The “splat” operator (*) is extremely useful and allows you to take all sorts of crazy shortcuts, the kind of shortcuts that split your wig the first time you see them, but more importantly allow you to write über-concise, expressive code.
Say you have a nested array that you want as a hash, prepend a splat to your array and it will return a hash:
irb(main):001:0> hash = { :name=>"Steve Graham", :age=>24 }
=> { :name=>"Steve Graham", :age=>24 }
irb(main):002:0> array = *hash
=> [[:name, "Steve Graham"], [:age, 24]]Of debatable utility but while we’re here I might as well mention that you can do the reverse using
Hash[]irb(main):003:0> wow = Hash[array]
=> { :name=>"Steve Graham", :age=>24 }Wow! The thought of the amount of nonsense of code that you WON’T have to write now thanks to these little conveniences makes a little tear of joy bead up and teeter precipitously on my eyelid.
Ruby, I ♥ you. Emotional, truly emotional.
What else can we do with the splat? You can use the splat with a case statement:
males = %w(pharrell chad shae) females = %w(cameron jessica alyssa) justin_timberlake = case gender when *females "ladies good morning" when *males "gentlemen goodnite" when *males|females "hahahahaha and that's it" end
You can also use it on any class that includes Enumerable. What it does is call to_a on the object, which collects the entries of the object, in the case of a file, the lines:
irb(main):007:0> lines = *File.open('/etc/hosts'); pp lines
=>
["##\n",
"# Host Database\n",
"#\n",
"# localhost is used to configure the loopback interface\n",
…]Extra Credit:
Although not the splat operator itself, you can join an array using the splat, but in this case it’s an instance method of the Array class (Array#*).
irb(main):008:0> %w(a list of arbitrary words) * ", "
=> "a, list, of, arbitrary, words" -
Ruby Idioms & Shortcuts: Or Equals
I was recently looking for a Ruby authorization solution for the Platform app I’m developing. I had already settled on using Authlogic for authentication and session management, and wanted something that would play nice with what I had so far. Lockdown was one of the authorization libraries that I considered, but unfortunately it was unsuitable for my requirements.
For those interested in Lockdown there is a sample Rails app on GitHub. It was something I considered to make my decision whether to use Lockdown or not. During my examination of the App I noticed code in the ApplicationController that made me shudder:
class ApplicationController < ActionController::Base … def current_user_session if defined?(@current_user_session) && !@current_user_session.nil? return @current_user_session end @current_user_session = UserSession.find end endExtremely long winded.
What this method is doing is checking if the instance variable is defined i.e. has a value been assigned to it? Even assigning it nil is sufficient. If it has, it returns a string description of the object being checked, in this case “instance-variable”, which of course evaluates as true in Ruby, so the second half of the if condition is evaluated. This is checking that the instance variable does not have a nil value in an extremely backwards way, i.e. is the object not nil? SMH. If both conditions evaluate as true the instance variable is returned, if not, it is assigned the result of the find class method on the UserSession model.
As alluded to before, everything other than nil or false evaluates as true in Ruby, also if an object is undefined, the defined? operator will actually return nil, so if one was so inclined as to use an if block, all that would be necessary would be:
class ApplicationController < ActionController::Base … def current_user_session if @current_user_session return @current_user_session end @current_user_session = UserSession.find end endIf @current_user_session is undefined or has a nil value, the block will not evaluate and @current_user_session will be assigned using the class method of the UserSession model. Immediately we have trimmed some cruft off of this, but this is Ruby, and as is often the case, there is a better way.
Enter the equals or operator:
class ApplicationController < ActionController::Base … def current_user_session @current_user_session ||= UserSession.find end endHoly S*** Batman! We just took that down to one line and it is functionally equivalent!
Ok, what is this equals or operator? How does it work? It checks the left hand side and if it evaluates as true, the left hand side is returned, otherwise the result of the right hand side is assigned to the left hand side of the operator and returned.
I duly patched the app and sent a pull request to the maintainer, because this sort of code belies a poor understanding of Ruby and immediately dissuaded me from seriously considering Lockdown further. If the example app is written in such a style, I might reasonably infer that the library is written as such too. I thought others might come to the same conclusion.
The equals or operator: So short, so sweet, so necessary!
-
Seeing Metaclasses Clearly. By _why←link!
I was going to do another Ruby idioms post on the whole class « self; self; end thing. However _why already did it a long time ago, and did a very good job of it too. _why was a valuable member of the Ruby community. It’s a shame that he disappeared.
-
Ruby Idioms & Shortcuts: Symbol#to_proc
Say you have a collection of names in lowercase, names are proper nouns, so it’s proper grammar for them to be capitalised. How might one go about doing that in Ruby?
irb(main):001:0> %w(john paul ringo george).map { |p| p.capitalize }
=> ["John", "Paul", "Ringo", "George"]Calling a method on each member of a collection is a very frequently performed operation, and passing a block to an enumerator method just for this purpose gets very tedious fast.
Thanks to the dynamic nature of Ruby, one can open and extend classes at runtime. One of the neater bits of syntactic sugar I have seen is Symbol#to_proc. I believe it first appeared in Ruby Extensions, but is more widely known thanks to Ruby on Rails.
So instead of the above, we can now do the following instead:
irb(main):002:0> %w(john paul ringo george).map(&:capitalize)
=> ["John", "Paul", "Ringo", "George"]Wow, that’s a cool shortcut, but how does it work?
First of all, look at the initial example. It might help to imagine that there are parentheses surrounding the block that is passed to the map method. It might make it a bit easier to understand when doing A-B comparisons between the first and second examples. As parentheses in Ruby are optional when they don’t add to the readability of the code, or the code won’t confuse the interpreter, they are usually omitted, as they were in this case.
Ok, lets walk through the second example. The map method is being called on an array literal containing the names of The Fab Four. The map method, from the module Enumerable that is “mixed in” to the Array class, invokes a block argument once for each element of self, in this case the array, and returns a new array containing the values returned by the block. However in this case, we don’t have a block, we have &:capitalize. What the hell is that? It’s another one of those things that make you think “Wow! Ruby is genius!”. When a unary ampersand is prepended to an object in Ruby, if the object is not a Proc object, the interpreter attempts to convert the object to a proc by calling to_proc on it. Since :capitalize is a Symbol, not a Proc, Ruby goes along and sends the to_proc message to :capitalize, thankfully both Rails and the Ruby Extensions project extend the Symbol class with a to_proc or at this point things would blow up in your face in a horrible mess.
So how does it work? Let’s look at the Rails implmentation:
class Symbol def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end endAdmittedly it’s not the most readable piece of code, so let me explain how it works
- A new Proc object is instantiated.
- The first argument, the object passed to the block by the enumerator is called on, in our exmaple one of the names, is removed from args
- The symbol itself is sent as a message with the remaining arguments to the object. There aren’t any in our example, but this is what makes it possible to do the magic with inject.
Rails’ implementation is more complex than you might require, allowing multiple arguments to be passed with the method call allowing things like this:
irb(main):003:0> [10, 6, 3].inject(&:*)
=> 180While being cool, I would consider this to be a corner case use for Symbol#to_proc, the most common use case being the object.enumerator(&:method) idiom. Unfortunately, the additional complexity of the implementation makes it slow as f***.
If you don’t need the additional functionality of passing multiple arguments, you can monkey patch Symbol with this:
class Symbol def to_proc Proc.new { |obj| obj.send self } end endYou’ll find the Rails implementation over 3 times slower than using a block, but this version is only marginally slower than using a block.
As of Ruby 1.9, Symbol#to_proc is native Ruby. It has also been back ported to 1.8.7 but you might not be aware, if as I did you thought that the default Ruby docs targeted the latest release of that branch. In fact the docs cover 1.8.6!
I’m not sure if the native implementation supports multiple arguments a la Rails, but if it does I hope the performance is an improvement on the Rails implementation.
There you have it ladies and gents! Symbol#to_proc, a tasty piece of sugar!
Tue02Mar
Fri19Feb
Tue16Feb
Fri12Feb
Sat06Feb
Fri05Feb
Tue02Feb
Sat30Jan
Mon25Jan
Thu21Jan
Wed20Jan
Mon11Jan
Thu24Dec
Sun20Dec
Thu17Dec