Felipe Elias Philipp Winner RPCFN #1 (Reprint)

Note: This article first appeared on 8th Oct. 2009 but the original is not accessible; hence the reprint.

In this brief interview, Satish Talim of RubyLearning talks to Felipe Elias Philipp of Brazil, winner of the first-ever Ruby Programming Challenge For Newbies.

Felipe Elias Philipp

Satish>> Welcome Felipe and thanks for taking out time to share your thoughts. For the benefit of the readers, could you tell us something about your self?

Felipe>> Thanks Satish for the opportunity. Well, about me… I’m a Brazilian guy, a web developer and a Mac user. I’m 22 years old and I started to program at school, since I was 16. Since then, programming has become my life and I can’t imagine myself doing any other thing.

Satish>> How did you get involved with Ruby programming?

Felipe>> I discovered Ruby through Rails on a well-known website by Brazilians: iMasters. I was just amazed as it was so easy to understand the Ruby code and I could solve the problems in a very simple way. This got me very motivated and I became more interested in the subject.

Continue reading “Felipe Elias Philipp Winner RPCFN #1 (Reprint)”

What are the Twelve Rules of Sinatra? (Reprint)

Note: This article first appeared on 19th July. 2009 but the original is not accessible; hence the reprint.

The Twelve Rules of Sinatra

The Twelve Rules of Sinatra: Download this as a Free Report.

Recently, I was reading Scott Adams’ (of Dilbert fame) blog post “Rule of Twelve” where he stated:

The Rule of Twelve states that if you know twelve concepts about a given topic you will look like an expert to people who only know two or three. If you learn more than twelve concepts about a topic, the value of each additional one drops off considerably. Allow me to be the first to confess that twelve is not a magic and inviolable number.

He also wrote a follow-up post to support his statement: “Twelve Rules of Energy Efficient Building“.

This made me wonder, could we apply the same “Rule of Twelve” to Sinatra?

Jeremy EvansHere is Jeremy Evans’ take on this:

  1. Just like Rails, keep your controller/actions simple, and put most of your business logic in your models. This makes testing and code reuse easier.
  2. Also like Rails, avoid excess logic in your views.

    Continue reading “What are the Twelve Rules of Sinatra? (Reprint)”

20+ Rubyists are using Sinatra – Do you? (Reprint)

Note: This first appeared on 29th June 2009 and is being reprinted as the original is not accessible.

20+ Rubyists are using Sinatra – Do you?

With Sinatra you can quickly create your own tiny web-applications in Ruby and write lots of small services. RubyLearning caught up with some Rubyists working with Sinatra and asked them as to why, how and where they use Sinatra.

Aaron QuintAaron Quint>> I’ve been using Sinatra all over the place. With Vegas I’ve been using it as a way to provide simple web interfaces to existing code. I’ve also been using it to prototype new application ideas. When not using Sinatra, I’ve been using some of the same basic ideas in JavaScript with Sammy.js. In general, Sinatra is just fun to use as it provides the most direct and clean route to get an idea or a piece of code on the web. Read Aaron’s interview on Sinatra.

Adam KeysAdam Keys>> I’m using Sinatra for two things. For personal stuff, I always reach for Sinatra when I want to prototype an idea. It’s easy to get something in place so I can iterate on the idea quickly. Sinatra is great for deploying prototypes too!

Andrew Neil
Bruno Miranda
Chris Strom
Corey Donohoe
Doug Sparling
Jeremy Evans
Graham Ashton
Hasham Malik
James Edward Gray II
Jeremy Raines
Julio Javier Cicchelli
Karel Minarík
Matt Todd
Nick Plante
Peter Cooper
Piyush Gupta
Sam Goebert
Sau Sheong Chang
Saurabh Purnaye
Twitter

Continue reading “20+ Rubyists are using Sinatra – Do you? (Reprint)”

Karel Minarik: How do I learn and master Sinatra? (Reprint)

Note: This is reprint of the blog post that appeared on 13th July 2009, as the original is not accessible.

Welcome to the fourth installment on the RL blog, of a mini series – “How do I learn and master Sinatra?” – by top Rubyists using Sinatra. The interview series will provide insight and commentary from these notable Sinatra developers, with the goal of facilitating and providing answers to the questions Ruby beginners face on how to learn and master Sinatra.

Satish>> Karel Minarik, could you tell us something about yourself – your background, where you are based?

Karel MinarikKarel Minarik>> I’m Karel Minarik, web designer and developer living in Prague, Czech Republic. I have graduated in Philosophy, not Computer Science, which may explain why I love Ruby a lot, and why I prefer solving “naming things” over “cache invalidation” problems. I earn my bread by designing interfaces, writing Ruby, JavaScript, HTML/CSS and giving people advice or teaching them new tricks. I blog in undecipherable intervals on Restafari.org and publish code regularly at Github.

Satish>> Are there any pre-requisites for a person to start learning Sinatra?

Karel>> Very few: you just need to know Ruby a little bit. The rest you can and will learn along the way. In fact, Sinatra is wonderful teaching tool to deepen your knowledge of Ruby as a general programming language, web application architectures, HTTP and REST principles, concept of middlewares, and so on.

Sinatra Icon
:)

Continue reading “Karel Minarik: How do I learn and master Sinatra? (Reprint)”

Corey Donohoe: How do I learn and master Sinatra?

Note: We are re-printing this blog post that appeared on 6th July 2009, as the original post is not accessible.

Welcome to the first installment on the RL blog, of a mini series – “How do I learn and master Sinatra?” – by top Rubyists using Sinatra. The interview series will provide insight and commentary from these notable Sinatra developers, with the goal of facilitating and providing answers to the questions Ruby beginners face on how to learn and master Sinatra.

Satish>> Corey Donohoe, could you tell us something about yourself – your background, where you are based?

Corey DonohoeCorey Donohoe>> I’m Corey Donohoe. I’m based out of Boulder, Colorado – USA. My background is in computer science and system administration though I prefer hacking to either of those labels. I’m a pretty normal dude, I enjoy cycling, music, coffee, micro brews, and all the other awesomeness that my home state has to offer. I’ve been working for Engine Yard since March of ’07 doing everything from app support to internal development. I’m currently 1/2 of our internal integrations team.

Sinatra’s greatest strength is its flexibility

Satish>> Are there any pre-requisites for a person to start learning Sinatra

Corey>> There aren’t any hardcore prerequisites per se; Ruby and experience in a Ruby web framework is a plus. HTTP verbs play a huge role in Sinatra, as well as things like query and post params.

Sinatra Icon

Continue reading “Corey Donohoe: How do I learn and master Sinatra?”

All about Struct

All about Struct

This guest post is by Steve Klabnik. Steve is a Rubyist, writer, and teaches Ruby and Rails classes with Jumpstart Lab. He maintains Draper, Hackety Hack, and Shoes, and
contributes to Rails from time to time.

Steve Klabnik One of my favorite classes in Ruby is Struct, but I feel like many Rubyists don’t know when to take advantage of it. The standard library has a lot of junk in it, but Struct and OStruct are super awesome.

Struct

If you haven’t used Struct before, here’s the documentation of Struct from the Ruby standard library.

Structs are used to create super simple classes with some instance variables and a simple constructor. Check it:

Struct.new("Point", :x, :y) #=> Struct::Point
origin = Struct::Point.new(0,0) #=> #

Nobody uses it this way, though. Here’s the way I first saw it used:

class Point < Struct.new(:x, :y)
end
origin = Point.new(0,0)

Wait, what? Inherit…from an instance of something? Yep!

1.9.3p194 :001 > Struct.new(:x,:y) => #<Class:0x007f8fc38da2e8>

Struct.new gives us a Class. We can inherit from this just like any other Class. Neat!

However, if you’re gonna make an empty class like this, I prefer this way:

Point = Struct.new(:x, :y)
origin = Point.new(0,0)

Yep. Classes are just constants, so we assign a constant to that particular Class.

If you’d like, you can pass a block to the Struct:

Point = Struct.new(:x, :y) do
  def translate(x,y)
    self.x += x
    self.y += y
  end
end

Now we can do this:

origin = Point.new(0,0)
origin.translate(1,2)
puts origin #=> <struct Point x=1, y=2>

OStruct

OStructs are like Struct on steroids. Check it:

require 'ostruct'
origin = OpenStruct.new
origin.x = 0
origin.y = 0
origin = OpenStruct.new(:x => 0, :y => 0)

OStructs are particularly good for configuration objects. Since any method works to set data in an OStruct, you don’t have to worry about enumerating every single option that you need:

require 'ostruct'

def set_options 
  opts = OpenStruct.new
  yield opts
  opts
end

options = set_options do |o|
  o.set_foo = true
  o.load_path = "whatever:something"
end

options #=> #<OpenStruct set_foo=true, load_path="whatever:something">

Neat, eh?

Structs for domain concepts

You can use Structs to help reify domain concepts into simple little classes. For example, say we have this code, which uses a date:

class Person
  attr_accessor :name, :day, :month, :year

  def initialize(opts = {})
    @name = opts[:name]
    @day = opts[:day]
    @month = opts[:month]
    @year = opts[:year]
  end

  def birthday
    "#@day/#@month/#@year"
  end
end

and we have this spec

$:.unshift("lib")
require 'person'

describe Person do
  it "compares birthdays" do
    joe = Person.new(:name => "Joe", :day => 5, :month => 6, :year => 1986)
    jon = Person.new(:name => "Jon", :day => 7, :month => 6, :year => 1986)

    joe.birthday.should == jon.birthday
  end
end

It fails, of course. Like this:

$ rspec
F

Failures:

1) Person compares birthdays
Failure/Error: joe.birthday.should == jon.birthday
expected: "7/6/1986"
got: "5/6/1986" (using ==)
# ./spec/person_spec.rb:9:in `block (2 levels) in'

Finished in 0.00053 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/person_spec.rb:5 # Person compares birthdays

Now. We have these two birthdays. In this case, we know about why the test was failing, but imagine this failure in a real codebase. Are these month/day/year or day/month/year? You can’t tell, it could be either. If we switched our code to this:

class Person
  attr_accessor :name, :birthday

  Birthday = Struct.new(:day, :month, :year)

  def initialize(opts = {})
    @name = opts[:name]
    @birthday = Birthday.new(opts[:day], opts[:month], opts[:year])
  end
end

We get this failure instead:

$ rspec
F

Failures:

1) Person compares birthdays
Failure/Error: joe.birthday.should == jon.birthday
expected: #
got: # (using ==)
Diff:
@@ -1,2 +1,2 @@
-#
+#
# ./spec/person_spec.rb:9:in `block (2 levels) in'

Finished in 0.00092 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/person_spec.rb:5 # Person compares birthdays

We have a way, way more clear failure. We can clearly see that its our days that are off.

Of course, there are other good reasons to package related instance variables into Structs, too: it makes more conceptual sense. This code represents our intent better: a Person has a Birthday, they don’t have three unrelated numbers stored inside them somehow. If we need to add something to our concept of birthdays, we now have a place to put it.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Also, do check out Steve’s other articles: “How do I test my code with Minitest? and “How do I keep multiple Ruby projects separate?” on RubyLearning. Thanks!

Technorati Tags: , ,


(Powered by LaunchBit)

Ruby in 2012

Matt Aimonetti

Ruby is more popular than ever, but it’s also not as trendy as it used to be. rubylearning.com students1 asked a few questions to about his vision of Ruby in 2012 and for the future.

is a well-known Rubyist, technical writer, speaker and active open-source contributor. He currently works as a software architect for LivingSocial. Prior to joining LivingSocial, Matt worked for Sony PlayStation.

How does Ruby fit in with the future, as you see it?

: This is a really hard question. If I could predict the future, I would probably already be rich. Ruby is a very powerful and flexible language.

Very much like Python, Ruby is a great glue language, a great language for the web and overall a language that allows you to get a lot done before you hit the language limitations.

The ecosystem also keeps growing and there seems to be more and more people focusing on performance and documentation which are two things Ruby could still improve a lot on.

I think it’s quite obvious that the pendulum is swinging back and server side code is going to be more and more API oriented with smart clients consuming these services. Ruby is great for that because services need to be easy to write, easily to maintain, well documented and flexible. I wrote a DSL to do just that using Ruby and it would have been harder in any other language.

So, to answer the question more directly, I think that Ruby will keep on playing a major role in web development but at the same time, developers will become more and more polyglot and might switch back and forth between languages.

I have talked to people that think that Ruby is falling by the wayside, even to the point where they say that Rails is killing Ruby. What do you think?

Matt Aimonetti: I wouldn’t say that Ruby is falling by the wayside, what’s going on is that Ruby outgrew the startup world where it became very popular a few years ago. However, you now find Ruby (and Rails to that matter) in a lot of more established places thanks to its efficiency of development, strong focus on testing, active community and great ecosystem.

When some people say that Rails is hurting Ruby, I think what they mean is that for them Ruby’s fate is directly related to Rails’. If Rails doesn’t manage to stay the web framework of reference, it might hurt the language. This is certainly not entirely wrong. Without Rails, Ruby wouldn’t have been as popular, but at the same time, there is much more to Ruby than Rails and I think that as a community we need to seriously start looking at all the great things we can do with Ruby outside Rails.

What is your opinion on Node.js? Is this the future? Do you think Node.js will beat Ruby in web application development?

: This is a question I often get. I personally like node.js, I think it’s fun, easy to get started and with CoffeeScript, writing JavaScript (JS) is almost fun. That said, Node is really young, not very well documented and relies extremely heavily on callbacks which can be quite confusing at times. My experience with Node is limited, but as my personal project started growing, I started struggling to keep my code simple and easy to maintain. Because I already know Ruby quite well and because equivalent tools exist in Ruby land, I don’t see a real need to use Node besides being the new cool framework.

But the project is fast growing, the cross-platform focus is welcomed and I think that for some developers, Node.js can be a great solution, especially when developing simple web APIs.

Will it “beat” Ruby? Well, a framework and a programming language are two different things. Will it beat Rails in popularity, that’s a possibility due to the fact that JavaScript is becoming very popular. However, some of the issues I mentioned earlier might prevent Node.js to become as popular as some people seem to believe. Finally, at the end of the day, if a JS framework becomes a better solution than anything else I use, I will certainly switch. But so far, I don’t see that happening.

Do you think Ruby is the best programming language to be introduced to newbies to get them started in programming?

Matt Aimonetti: I do believe Ruby is a great language to learn some of the basis of programming, especially Object Oriented Programming. It allows students to get easily started and to build things quickly. However, different people learn differently and are attracted to other things and parts of Ruby can be quite hairy. To properly learn a language, you also need to have a way to practice and quickly see the fruit of your labor. That’s why If you are a designer, I might suggest you start with JavaScript and then move on to a better designed, high level programming language like Ruby or Python. Finally, you need to look at your motivation being learning a new language.

If you want to learn programming because you want to work in this field, consider starting learning a language which will allow you to easily start working (hint: there are a lot of Rails positions out there waiting for you). But don’t stop there, keep learning new languages and way to solve problems using code.

How to become a better coder? I still feel it’s hard to get involved contributing to OSS, could you give us some advice?

Matt Aimonetti: I personally get better when I practice a lot and when overcoming problems I didn’t know how to solve before I started. Open Source contribution is a great way to get feedback and learn from others. I think that with tools such as Git and GitHub, OSS contribution has become much easier than ever. That said, a lot of developers think that their contributions have to be significant, and, that’s in my mind, a mistake. Start by contributing documentation, examples and helping others. File bug reports and try to reduce them to an easier to handle case. That might seem trivial to you, but it’s extremely useful, it will teach you a lot about the project you are involved with, its design, the pros/cons and how an OSS project is run. Doing that will help you debug and diagnose problems faster and when added to the design knowledge and communication skills you would have acquired, you have all the ingredients of a good developer. Another thing I like to do is to pick something that seems absolutely impossible for me to do. If you only know Ruby, memory management and writing code C might seem hard. Give yourself a reasonable time frame and a challenge such as 6 months to have a small C program that will do X, Y and Z. Keep it small and simple and don’t forget to have fun. At first it will be hard, but don’t give up, keep trying until you learned something you thought was impossible. When you will go back to writing Ruby or whatever language you write, you will look at things from a different angle.

Finally, the last thing I would suggest is to never feel too comfortable in your daily programming tasks. If you are to the point where you just execute and aren’t challenged, you might want to consider talking to your supervisor about giving you more challenging tasks.

Are you excited about MobiRuby? Do you think it will become a viable platform for iOS development?

Matt Aimonetti: MobiRuby is being developed on top of mruby, the new Ruby implementation written by Matz that’s targeting embedded device and offering an alternate for Lua and to some extent JavaScript. I’m quite excited about mruby and its potential and I wrote about both mruby and MobiRuby a couple days ago. Basically, from my view point MobiRuby is an interesting project but it will have to overcome some serious challenges described in details in my blog post. My hope is that thanks to the Ruby language, MobiRuby will be able to transcend Cocoa/Android API to offer an easier, simpler API making mobile development more fun and more easily accessible.

This is quite a big challenge, but I do believe this is something that can be done and that might change the way mobile development is done.

I hope you found this article useful. What are your thoughts? Feel free to ask questions and do give your opinion in the comments section of this post. Matt would only be too happy to reply. Thanks!

Technorati Tags: , ,

  1. Thanks to Michael Kohl, Samnang Chhun and Victor Goff.


(Powered by LaunchBit)

The 5 Most Popular Articles of 2011 on RubyLearning

(Based on Twitter Re-tweets)

The year 2011 saw RubyLearning’s awesome guest authors write and share their knowledge with others. If you missed any of these useful articles then here’s the roundup of the 5 most popular articles of 2011 on RubyLearning. Enjoy!

Throw, Catch, Raise, Rescue… I’m so confused!

Avdi Grimm explains the usage of Throw, Catch, Raise, Rescue in the Ruby programming language.

You’ve probably noticed that Ruby has throw and catch… but they don’t seem to be used the way you’re used to in other languages! And there are also these begin, raise and rescue statements that seem to do the same thing. What’s going on here?

Read the rest of the article: Throw, Catch, Raise, Rescue… I’m so confused!

Performance Testing Rails Applications – How To?

Gonçalo Silva shows you how to do performance testing of your Rails applications.

Rails’ performance testing tools allow you to quickly detect performance bottlenecks. As a rule of thumb, use benchmarking to detect the problem and then use profiling to understand it.

Read the rest of the article: Performance Testing Rails Applications – How To?

Do you ponder what to name things in your code?

Evan Light asks – do you ponder what to name things in your code?

Most of the time, someone has to maintain that pile of crap you just birthed! It may be someone else. It may be you! But it’s always wise to pretend that the person who will own your code next is an axe-wielding lunatic who knows where you live!

Read the rest of the article: Do you ponder what to name things in your code?.

How do I smell Ruby code?

Timon Vonk talks about Ruby code smells in an effort to improve Ruby code.

Writing bad code isn’t a bad thing. Not understanding the problem you’re trying to solve any better after having written that piece of code is. Fortunately, that happens far less often.

Read the rest of the article: How do I smell Ruby code?

How do I test my code with Minitest?

Steve Klabnik introduces the readers to Ruby’s minitest.

You run your program, try a few different inputs, check the outputs, and see that they’re right. Then, you make some changes in your code, and you’d like to see if they work or not, so you fire up Ruby and try those inputs again. That repetition should stick out. There has to be a better way.

Read the rest of the article: How do I test my code with Minitest?

Your turn: Share the link to a roundup post you’ve written. If you’ve never written a roundup, try it this week. Be sure to share the link to your post here!

Technorati Tags: , ,


(Powered by LaunchBit)

Let’s Talk About Conditional Expressions

This guest post is by Evan Light a test-obsessed developer, the author of several rarely used gems, and the curator of Ruby DCamp. When he’s not a talking head at conferences, he’s usually working at home as a freelance developer remotely mentoring a developer, working for one or more startups, playing with open source, keeping his wife and four cats company, hacking nonsensically, talking at people on the internet, and/or attempting to lose weight (or any combination of the above). What else do you do when you live 3 hours from civilization?

Evan Light You know what bugs me? People who don’t write idiomatic conditionals in Ruby.

Many folks, especially those who came out of Java, .NET, or C/C++, use and abuse the ternary. The ternary is a humble little production rule that works like so:

<boolean expression> ? <eval this expression if truthy> : <eval if falsey>

The ternary can be useful if the truthy and falsey cases are terse and well-named. However, it’s common to see multi-line ternaries or, even worse, nested ternaries. For example:

By the way, the above example comes out of Rails.

Accepting that the above is just painful, how could we make it hurt less? Specifically, let’s focus on the nested ternary on Line 7 (accepting that there are other ways that the code can be made clearer).

For starters, let’s DRY up these Hash lookups:

Now let’s unravel this into more idiomatic Ruby. We’ll extract the outer ternary into a functional style if-else. Remember that every expression in Ruby returns the value of its last executed expression. The if-else returns either the value of the computed String in the if or the empty String else. It has the advantage of containing more English words and fewer characters that resemble modem line noise or PERL.

We can get rid of this else. After all, it doesn’t contain any logic. Let’s just make it the default value for method_prefix and then assign a new value only when prefix is truthy.

Ah so what this code really cares about, first and foremost, is whether prefix is falsey. When it’s falsey, it just returns an empty String! Otherwise, if it’s not, it generates a String possibly using the value of prefix if and only if prefix is not true – not a boolean.

So why should we try to avoid ternaries? Because, when used within a complex expression, they tend to lack the clarity of intent of an if-else. The lack of clarity likely resulted in the less DRY previous implementation. Once we introduced more clarity, it became obvious how this code could be DRY’d up, resulting in better readability.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Subscribe to the waiting list of the free, online “Intermediate Ruby Course“. As a bonus, get a free copy of the “Introduction to Rack” eBook (.pdf format).

Technorati Tags: , ,


(Powered by LaunchBit)

Do you ponder what to name things in your code?

This guest post is by Evan Light a test-obsessed developer, the author of several rarely used gems, and the curator of Ruby DCamp. When he’s not a talking head at conferences, he’s usually working at home as a freelance developer remotely mentoring a developer, working for one or more startups, playing with open source, keeping his wife and four cats company, hacking nonsensically, talking at people on the internet, and/or attempting to lose weight (or any combination of the above). What else do you do when you live 3 hours from civilization?

Why should I care?

Evan Light “The hell with clean code!1, you say. “I’ve got stuff to get done!” You beat on keys for a while. Characters appear. The characters don’t make a lot of sense but, hey, the compiler compiles it or the virtual machine interprets it. Things happen. Eventually, an application emerges.

Success? Hell no!

Most of the time, someone has to maintain that pile of crap you just birthed! It may be someone else. It may be you! But it’s always wise to pretend that the person who will own your code next is an axe-wielding lunatic who knows where you live.

The worst sin that I’ve seen people make in their code: choosing poor names… for their classes, methods, literals, you name it.

“I don’t have time to sit around thinking about the perfect name for a class! Besides, I know how the code works! I can fix it.”

Oh, yeah? You may now. But how about in a month? Or three? Or a year? Wait… will you even be working for this company or on this project in a year? Who inherits this code?

Prototypes, spikes, and other rationalizations

Occasionally, developers invoke the “p” word: prototype. Prototypes are ugly little creatures that live only a short while.

At least that’s the myth.

The truth of the matter is that prototypes don’t exist. Prototypes don’t get thrown away. What happens when you show a manager working code? He says, “Great! Here’s your next feature!”

“But…”, you start to say.

“But what? It’s working! Marvelous! Right, here you are. Next feature!”

Heard of a “spike”? That’s basically a small prototype that you may not tell management about. You spend maybe 30 minutes working on one. The pain of throwing away the code is lessened. But even then it may offend your sensibilities. And that code is going to be ugly too.

We tell ourselves that the code will be temporary. Most of the time, this just isn’t so. These techniques are rationalizations for writing ugly code that will likely outlive its intended lifespan.

Think about the future!

So don’t throw that code away! Don’t prototype. Don’t spike2.

Dave Thomas sometimes describes writing an application as writing a Domain Specific Language. That is, creating an application is akin to developing a semantically meaningful API to describe an application’s behavior.

Therefore, the smartest thing you can do, when starting a new application, is to cultivate an understanding of the overall problem the application is intended to solve.

How can we do this? Personally, I favor contemporary Test Driven Development techniques:

For a given feature:

  1. Describe, in English, what the feature is trying to accomplish
  2. Exercise the API that I wish I’d write as a test
  3. Make the test pass
  4. Compare 1 & 2
  5. Refactor

For instance, consider this simplistic example:

Names should match intent

The English uses the word “subscribe”. That’s the action that I want the user to perform. So I make it the method name because that’s what I want to tell the user to do. That’s the message that I want to send the user.

Now what if I need an entity to representation that relationship between a User and a Plan?

I’ve seen (and written) some egregiously bad code in situations like this. Once upon a time, my initial reaction would be to call such a thing a “UserPlan”.

That’s just vile and disgusting. Sure, it conjoins the two entities but it does so like Siamese twins!

The better answer should be in plain sight. I used the word “subscribe” in the description! Call that entity a “Subscription”!

But maybe your description was

That would probably cause me to write sample code

It’s still valid though I did less to model the relationship between the User and the Plan because words matter and naming matters.

Counter example

So what happens when we name things badly?

Is “UserPlan” so bad? Perhaps not. But UserPlan only represents a relationship between two entities. Perhaps I need a greater monstrosity to make the point plain.

So what is a SelfpropelledFourWheelGroundVehicle? It’s pretty plainly a Car/Automobile. But it’s a disgusting name. Yet these are the kinds of names that people frequently use in their code due to lack of effort!

Or there’s the other direction: Haskell developers often like to abstract functions such that they have no clear applicability to a domain. That is, their functions will have semantically meaningless variables such as “x” and “xs”. I’m told this is because Haskell has its roots in Lambda Calculus. Be that as it may, mathematical variables have only place in code: in implementing a mathematical calculation!

How would you feel maintaining code where the classes, literals, and methods read like that?!

How productive would you be working in such code? If you cannot trust the names in a code base to accurately represent the ideas at work then you need to understand vast swaths of the code base to be the least bit productive!

Conclusion

If you did not before, I hope that you now have a better appreciation why it is worth your time to get the names right in your code. It will make yours, your colleagues’, and any who later touch your code lives better and more productive.

And if you don’t use good names, I have an axe and I know where you live.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Subscribe to the waiting list of the free, online “Intermediate Ruby Course“.

Technorati Tags: , ,

  1. Robert Martin also wrote about this topic, and, in part, inspired this diatribe with the first chapter of his book, Clean Code.
  2. Yes, this is a sweeping generalization. Yes, I occasionally spike on code. However, I only do this for technically challenging pieces which is to say very infrequently. And I throw my few spikes away.

My Ruby Book now available in .mobi and .epub formats

My Ruby Book now available in .mobi and .epub formats

My Ruby book has been available since 2006 in .pdf format. It’s now available, completely updated for Ruby 1.9, in .mobi and .epub formats.

Ruby eBook The Ruby eBook covers Ruby 1.9 and has all the Core Ruby programming topics on the RubyLearning.com site. This Ruby eBook, is the ideal companion for students in the Online Ruby Class at RubyLearning.org and provides an overview of Ruby programming.

The eBook is over 230 pages and is in both .mobi and .epub formats. For a limited time, the cost of this eBook (both formats together) is only US$ 5 and is being collected to help RubyLearning maintain the site and the eBook, and provide quality content to you. Please pay by Paypal to satish [at] rubylearning.org. Once you have paid email me at the same email id and I will email you both the formats of the Ruby eBook.

Here’s what one satisfied customer, Thomas Johan Eggum from Norway has to say:

After years with Java development and some various experience with the framework Ruby on Rails, I wanted to get a broader knowledge with the Ruby language. I stumbled over Satish’s website rubylearning.com, and decided to read the book “The Ultimate Guide To Ruby Programming”. I found the book easy to read and very efficient with regards to covering the essentials of Ruby. There is no confusing overhead, and the material is presented in an informative way. After each chapter there is a summary and an exercise part, making it easy to verify progress. I can highly recommend this book for those interested in learning Ruby. I also found the book helpful when studying towards the certification “Ruby Association Certified Ruby Programmer Silver”.

The eBook is also available on Amazon.

Please let me know what you think about the eBook once you get around to read it.

Technorati Tags: , , ,

Do you know Ruby Doctest?

Do you know Ruby Doctest?

This guest post is by Victor Goff, who enjoys mentoring Ruby at RubyLearning.org since 2008. You can reach him on IRC Chat #rubylearning on freenode.net. He also blogs occasionally at http://vgoff.posterous.com.

Victor Goff III Rubydoctest is a gem that we will be installing. The purpose of the gem is simply to provide a way to document our programs using IRB sessions, resulting in a way to provide usage examples as well as knowing when an expected use fails because of some update or changes to our program or environment.

Installing Ruby DocTest

Rubydoctest can be installed by doing the following from the command line:

$ gem install rubydoctest

If you are running Windows or using RVM the above should work (pending network/internet connectivity) but you may need to use sudo to install depending on your set up.

The parts of Ruby DocTest

Rubydoctest information can be contained within a comment or a comment block.

Let’s start by creating a file hello.rb:

def hello name
  "Hello " + name
end
=begin # This is the beginning of a comment block
doctest: hello " World" will return "Hello World"
>> hello "World"
=> "Hello World"
=end

We have our trusty method called hello, but we have added a comment block with doctest information inside. Other than the doctest: directive, it should remind you of an IRB session.

The doctest: directive is the human readable title of the test. If this isn’t supplied you would end up seeing ‘default’ as the title.

To use rubydoctest:

USAGE: rubydoctest [options] 

  rubydoctest parses Ruby files (.rb) or DocTest files (.doctest) for irb-style
  sessions in comments, and runs the commented sessions as tests.

  Options:
    Output Format:
      --html  - output in HTML format
      --plain - force output in plain text (no Ansi colors)

    Debug:
      --ignore-interactive - do not heed !!! special directives
      --trace     - turn backtrace on to debug Ruby DocTest
      --debugger  - include ruby-debug library / gem

Let’s go ahead and run the following command to see what happens here:

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello "World" will return "Hello World"
1 comparisons, 1 doctests, 0 failures, 0 errors

As you can see, we get passing tests. And if this were above the method definition it may even be collected during ri and rdoc generation (this process is outside the scope of this article.)

Refactoring with RubyDoctest

Once we have a simple test in place, and that test is passing, we can refactor it, with confidence that the method still passes.

I noticed that I used “String” + variable in this method, but realized that it may read a little better (and create only one object) if I use string interpolation:

def hello name
  "Hello #{name}"
end

Which I think should pass the test, but just for good measure, we want to actually test it:

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello "World" will return "Hello World"
1 comparisons, 1 doctests, 0 failures, 0 errors

And as we can see, it passes.

Next, we will fully develop our hello method so that it has some nice features.

Using RubyDoctest in a TDD manner

We will be starting our hello method over from scratch. Going through the full life cycle of a small method, and testing along the way. It will be conversational, and demonstrative, so that you can follow along as we go.

Starting with an idea

It all starts with an idea: I would like a hello method that will simply state “Hello World!” In order to make this happen, and have the documentation and the tests that I would eventually like to have, I place this in my hello.rb file:

=begin
doctest: hello returns “Hello World!”
>> hello
=> “Hello World!”
=end

And to make sure that it is written correctly, we do want to run the following command and get the information back from our test:

rubydoctest hello.rb
=== Testing 'hello.rb'...
ERR  | hello returns "Hello World!"
       NameError: undefined local variable or method `hello' for main:Object
         from hello.rb:3
       hello
1 comparisons, 1 doctests, 0 failures, 1 errors

This information, if we pause and read it, tells us exactly what we need to get it past this error. It states “undefined local variable or method ‘hello’” and from which line it was called. We have already made the assumption that we want a method, and so we can do the least amount to cause this ERR to no longer exist. (You may see it as a shade of yellow in your console.)

So let’s write the least amount of code that we can think of to get it to not error (I placed the following on lines 6 and 7, just below the comment block):

def hello
end

Once I save this, and run the rubydoctest command, I get the following:

rubydoctest hello.rb
=== Testing 'hello.rb'...
FAIL | hello returns "Hello World!"
       Got: nil
       Expected: "Hello World!"
         from hello.rb:4
1 comparisons, 1 doctests, 1 failures, 0 errors

Depending on your settings, you should get a red “FAIL” message as well as the next three lines. Regardless you will get the summary information with 1 comparisons, 1 doctests, 1 failures and 0 errors.

The error count is 0, which means that we have progressed past the yellow ERR message. We will generally always want to work past ERR messages first, then FAIL messages, until we get to OK.

Let’s go forward in our journey and get past this FAIL message.

Paying attention to the feedback we get, it states that we are getting nil when we are expecting “Hello World!”. I think it is fairly obvious that we can simply have the method return the string “Hello World!” and get this to pass. Simplistic, and exactly what we want:

def hello
  "Hello World!"
end

Simplistic and rids us of the failure in our test:

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello returns "Hello World!"
1 comparisons, 1 doctests, 0 failures, 0 errors

Again, in your console, you may actually see a green OK. The important thing to note is the 0 failures and 0 errors.

It continues with expanding ideas

Let’s think about what we have. A hello method that greets the world. Not too bad. But let’s say that we want to be able to use it to greet the world, but also to greet someone in particular. Continuing our program documentation, we add the following:

doctest: hello "reader" returns "Hello reader!"
>> hello "student"
=> "Hello student!"

Those three lines should be added to comment block and our entire file looks like so:

=begin
doctest: hello returns "Hello World!"
>> hello
=> "Hello World!"
doctest: hello "reader" returns "Hello reader!"
>> hello "student"
=> "Hello student!"
=end
def hello
  "Hello World!"
end

When we run the doctest (which we should do any time we make a change in either the documentation or in the code itself), we should get:

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello returns "Hello World!"
ERR  | hello "reader" returns "Hello reader!"
       ArgumentError: wrong number of arguments (1 for 0)
         from hello.rb:6
       hello "student"
2 comparisons, 2 doctests, 0 failures, 1 errors

From this we can see that the current way we want to use it by giving one argument is in error on line 6, because our method wants 0. That is what the “(1 for 0)” means. We are giving it one argument “student” and it is really what we want.

You may think that if we fix the error, the first test with either error or fail, and you would be right. When going through this process, you want to be careful to make small changes, as well as concentrating on the feature you are working on. So we will work on test hello “reader” returns “Hello reader!” until it passes. Until that happens, we will ignore the first test.

How might we get out of our error condition? Perhaps like this?

def hello name
  "Hello World!"
end

Notice how we added the argument of name to our method. We could have used something instead of name, perhaps arg or argument, but that simply states what it is, not what we should pass. In this way, what we call the argument helps to document our method as well.

As we have made a change, it is time to run rubydoctest again and see if we got past the error:

rubydoctest hello.rb
=== Testing 'hello.rb'...
ERR  | hello returns "Hello World!"
       ArgumentError: wrong number of arguments (0 for 1)
         from hello.rb:3
       hello
FAIL | hello "reader" returns "Hello reader!"
       Got: "Hello World!"
       Expected: "Hello student!"
         from hello.rb:7
2 comparisons, 2 doctests, 1 failures, 1 errors

As you can see, we went from ERR to FAIL, which is where we want to be. Ignoring the first test, we go from FAIL to OK (pass) in the simplest change we can think of:

def hello name
  "Hello student!"
end

Simply replacing ‘World’ with ‘student’, I think, should get this test to pass:

rubydoctest hello.rb
=== Testing 'hello.rb'...
ERR  | hello returns "Hello World!"
       ArgumentError: wrong number of arguments (0 for 1)
         from hello.rb:3
       hello
 OK  | hello "reader" returns "Hello reader!"
2 comparisons, 2 doctests, 0 failures, 1 errors

There we go. Now we can look for any ERR messages as they are critical to allowing our program to run. It is complaining about wrong number of arguments, this time in reverse of what our second test was complaining about a few moments ago.

Do we want to change the test? It is something we could consider. I think I like having the ability to have default behavior of no argument to say greet the world. And so I would leave the test as it is.

Changing the method itself to accept 0 or more arguments is likely the right thing to do here. Let’s give that a shot:

def hello *name
  “Hello student!”
end

Adding the * to the argument will give us the ability to accept 0 or more arguments. Let’s test and see if we are still in an error condition:

rubydoctest hello.rb
=== Testing 'hello.rb'...
FAIL | hello returns "Hello World!"
       Got: "Hello student!"
       Expected: "Hello World!"
         from hello.rb:4
 OK  | hello "reader" returns "Hello reader!"
2 comparisons, 2 doctests, 1 failures, 0 errors

Seems to be OK, as we are no longer in an error condition. And a fail condition leads us where to go. We are getting “Hello student!” when we don’t give any argument. Looking above at our program, we want something a little more dynamic. Let’s use name variable to give us what we want in the string.

def hello *name
  "Hello " + name + "!"
end

It looks good to me, let’s see what our tests tell us?

rubydoctest hello.rb
=== Testing 'hello.rb'...
ERR  | hello returns "Hello World!"
       TypeError: can't convert Array into String
         from hello.rb:3
       hello
ERR  | hello "reader" returns "Hello reader!"
       TypeError: can't convert Array into String
         from hello.rb:6
       hello "student"
2 comparisons, 2 doctests, 0 failures, 2 errors

As I know that prior to this change, the additional feature passed, we will ignore any change to that, and continue to make our default behavior work.

What is Ruby telling us? That we can’t convert Array into String on line 3. It must be the +() method. Let’s use .to_s method to convert the name variable explicitly to a string:

def hello *name
  "Hello " + name.to_s + "!"
end

and see if that takes us away from the error:

rubydoctest hello.rb
=== Testing 'hello.rb'...
FAIL | hello returns "Hello World!"
       Got: "Hello []!"
       Expected: "Hello World!"
         from hello.rb:4
FAIL | hello "reader" returns "Hello reader!"
       Got: "Hello [\"student\"]!"
       Expected: "Hello student!"
         from hello.rb:7
2 comparisons, 2 doctests, 2 failures, 0 errors

Good, we are out of error mode again, and back to FAIL mode. We can deal with that, and we got some more information. We got what appears to be an empty Array as indicated by the [] in the string. I would guess it is because of the *name that we added. Let’s try a default value instead. Still not changing any tests… but paying attention to the feedback from the first test.

def hello name='World'
  "Hello " + name.to_s + "!"
end

That gets us out of fail and into OK (pass) for each test as indicated below:

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello returns "Hello World!"
 OK  | hello "reader" returns "Hello reader!"
2 comparisons, 2 doctests, 0 failures, 0 errors
Refactoring in the Green

You might think we are done. But we are in ‘green’ mode and so are free to refactor our code. And looking at our code I see some things that can be improved.

def hello name='World'
  "Hello + name + “!"
end

Let’s use remove the .to_s method as we know we are going to get a string. Of course, we test after refactoring to make sure we are still good.

rubydoctest hello.rb
=== Testing 'hello.rb'...
 OK  | hello returns "Hello World!"
 OK  | hello "reader" returns "Hello reader!"
2 comparisons, 2 doctests, 0 failures, 0 errors

And we see we are still golden.

And on second thought, we can use string interpolation which to me makes it more readable, but also creates only one String object.

def hello name='World'
  "Hello #{name}!"
end

And of course, we run rubydoctest again to make sure we didn’t break anything, and we see that we are good.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Technorati Tags: , ,

Do you know how to write an internal DSL in Ruby?

Introduction

A Domain-Specific Language (DSL) is a (usually small) programming or description language designed for a fairly narrow purpose. DSLs are targeted at end users or domain specialists who are not expert programmers. Martin Fowler classifies DSLs into two styles – external and internal. An external DSL is a language that is different from the main programming language for an application, but that is interpreted by or translated into a program in the main language. An internal DSL transforms the main programming language itself into the DSL (our simple DSL is tied to the Ruby programming language).

Ruby code blocks

Ruby’s support for blocks (i.e., closures) is useful in defining internal DSLs.

Ruby code blocks (called closures in other languages) are chunks of code between braces or between do- end that you can associate with method invocations, almost as if they were parameters. A Ruby block is a way of grouping statements, and may appear only in the source next to a method call; the block is written starting on the same line as the method call’s last parameter (or the closing parenthesis of the parameter list). The code in the block is not executed at the time it is encountered. Instead, Ruby remembers the context in which the block appears (the local variables, the current object, and so on) and then enters the method. Matz says that any method can be called with a block as an implicit argument. Inside the method, you can call the block using the yield keyword with a value. Blocks are not objects, but they can be converted into objects of class Proc. One way a block can be converted to a Proc object is by passing a block to a method whose last parameter is prefixed with an ampersand. That parameter will receive the block as a Proc object:

def my_method(p1, &block)
  ...
end

instance_eval

The class Object has an instance_eval public method which can be called from a specific object. It provides access to the instance variables of that object. It can be called either with a block or with a string:

class Rubyist
  def initialize
    @geek = "Matz"
  end
end
obj = Rubyist.new
# instance_eval can access obj's private methods
# and instance variables
obj.instance_eval do
  puts self  # => #<Rubyist:0x2ef83d0>
  puts @geek # => Matz
end

The block that you pass to instance_eval helps you dip inside an object to do something in there. You can wreak havoc on encapsulation! No data is private data anymore.

instance_eval can also be used to add class methods as shown below:

class Rubyist
end
Rubyist.instance_eval do
  def who
    "Geek"
  end
end
puts Rubyist.who # => Geek

Deciding on a simple DSL

You are an expert Ruby programmer and your friends Victor, Michael and Satoshi (all 3 are novice chess players) have requested you to write a Ruby program for them, that could help them with a listing of the best black opening chess moves.

You tell your chess friends that if they need help they should individually send you a text file containing the white’s first move, as follows:

h4
a3
e4

h4, a3, e4 would be Ruby methods in your DSL program. Once we get the DSL to follow valid Ruby syntax, Ruby does all the work to parse the file and hold the data in a way that we can operate on it.

Victor is playing the black pieces and his opponent plays the opening white piece (say h4). Victor would like to know what’s the best strategy to counter white’s opening move of h4. He also would like to know, what if his opponent would have played a3.

Victor decides to send a text file to you.

The DSL program – chess_opener.rb

Being a Ruby expert, you dish out your first version of the DSL program – chess_opener.rb:

class ChessOpener
  def initialize
    @data = {}
    load_data
  end

  def self.load(filename)
    dsl = new
    dsl.instance_eval(File.read(filename))
  end

  def h4
    puts "=========="
    puts @data.assoc("h4")
    puts "=========="
  end

  def a3
    puts "=========="
    puts @data.assoc("a3")
    puts "=========="
  end

  def method_missing(method_name, *args, &block)
    msg = "You tried to call the method #{method_name}. There is no such method."
    raise msg
  end

  private
  def load_data
    @data = {"a3" => ["Anderssen's Opening Polish Gambit: 1. a3 a5 2. b4",
                      "Anderssen's Opening Creepy Crawly Formation: 1. a3 e5 2. h3 d5",
                      "Anderssen's Opening Andersspike: 1. a3 g6 2. g4"],
             "h4" => ["Koola-Koola continues 1.h4 a5",
                      "Wulumulu continues 1.h4 e5 2. d4",
                      "Crab Variation continues 1.h4 any 2. a4",
                      "Borg Gambit continues 1.h4 g5.",
                      "Symmetric Variation continues 1.h4 h5"]}
  end

end

Some explanation of code

The initialize method of your class ChessOpener creates a Hash object @data and populates it by calling the private method load_data. You have referred to the online list of chess openings to create the hash @data. The current program has the openings only for a3 and h4 moves, but you plan to add the other moves soon.

You want a simple and straightforward way to parse the DSL file. Something like:

my_dsl = ChessOpener.load(filename)

Also, you would like to accept the DSL file from the command line, something like:

my_dsl = ChessOpener.load(ARGV[0])

You write a class method load:

def self.load(filename)
  dsl = new
  dsl.instance_eval(File.read(filename))
end

The class method load creates a ChessOpener object and calls instance_eval on the DSL file (chess_opener_test.txt above). If you feed instance_eval a string, instance_eval will evaluate the string as Ruby code. In fact, this Ruby code is nothing but calls to the methods h4 and a3 which are respectively called. The methods h4 and a3 make use of Ruby Hash’s assoc method to extract the information about the particular (say h4) move.

The program also provides a method_missing method, in case the program fails to find a method say h5 (assuming Victor has typed that by mistake in the file chess_opener_test.txt.)

Running the DSL program

You next write the program – chess_opener_test.rb, ensuring that the files chess_opener.rb, chess_opener_test.rb and chess_opener_test.txt are in the same folder on your computer.

You now run your Ruby code as follows:

ruby chess_opener_test.rb chess_opener_test.txt

Here’s the sample output:

==========
h4
Koola-Koola continues 1.h4 a5
Wulumulu continues 1.h4 e5 2. d4
Crab Variation continues 1.h4 any 2. a4
Borg Gambit continues 1.h4 g5.
Symmetric Variation continues 1.h4 h5
==========
==========
a3
Anderssen's Opening Polish Gambit: 1. a3 a5 2. b4
Anderssen's Opening Creepy Crawly Formation: 1. a3 e5 2. h3 d5
Anderssen's Opening Andersspike: 1. a3 g6 2. g4
==========

In fact, in the next version of your DSL program, you plan to write the output to a file and send the same to Victor. Why don’t you fork this project and add-on some more functionality?

That’s it!

Feel free to ask questions and give feedback in the comments section of this post. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning email me at satish [at] rubylearning.org

Technorati Tags: , , ,

How do I use Sinatra to access the Google+ API?

How do I use Sinatra to access the Google+ API?

RubyLearning is conducting many free, online courses on Google+. Some participants wanted an answer to their question “How do I use Sinatra to access the Google+ API?” This blog post explains the same. Read on.

Pre-requisite

Install Sinatra, Git, Heroku, Bundler

Refer RubyLearning’s article on Google+.

Create a folder on your hard disk

Create a folder sinatragplus. This is where we will store our Sinatra app. Open a Bash shell in this folder.

Create the following folders also

Folder for app

Organize your application

Static Files

Static files are served from the public folder. Note that the public folder name will not be included in the URL. A file ./public/stylesheets/style.css is made available as rubylearning.org/stylesheets/style.css. Do note that we can have any directory layout under the public folder.

Layout

We will soon create layout.erb file in the views folder. This allows the basic layout of our site headers, footers and navigation panes to be controlled independently. A change in layout.erb is instantly applied across our whole site.

Let’s look at a sample file:

<html>
  <head>..</head>
  <body>
    <%= yield %>
  </body>
</html>

In the above file, note the usage of yield. The file calls yield at the point you want the content to be included i.e. it refers to some .erb in the views folder and the results of that .erb are stuck at the place, where you called yield.

Now, let’s write our app’s layout.erb file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>A Sinatra app to access Google+</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="description" content="RubyLearning.org" />
    <meta name="keywords" content="rubylearning,ruby,ruby programming,ruby course,sinatra course" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/style.css" />
    <link rel="icon" type="image/ico" href="/images/favicon.ico" />
  </head>
  <body>
    <%= yield %>
  </body>
</html>

Image

I am using a favicon (favicon.ico) for my app, which is stored in the public/images folder.

Stylesheet

We have our stylesheet namely style.css in the folder public/stylesheets.

body
{
  line-height: 1.6em;
}

h1 {
  color: #2A1959;
  border-bottom: 2px solid #2A1959;
}

h2 {
  color: #474B94;
  font-size: 1.2 em;
}

#footer {
  clear: both;
  border-top: 1px solid #2A1959;
  text-align: left;
  height: 50px;
  font-size: 70%;
  width: 100%;
}

#hor-minimalist-a
{
  font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
  font-size: 12px;
  background: #fff;
  margin: 45px;
  width: 480px;
  border-collapse: collapse;
  text-align: left;
}
#hor-minimalist-a th
{
  font-size: 14px;
  font-weight: normal;
  color: #039;
  padding: 10px 8px;
  border-bottom: 2px solid #6678b1;
}
#hor-minimalist-a td
{
  color: #669;
  padding: 9px 8px 0px 8px;
}
#hor-minimalist-a tbody tr:hover td
{
  color: #009;
}

View

A view is responsible for generating a user interface, normally based on data. For example, an online store will have a list of products to be displayed on a catalogue screen. The view accesses the data and formats it for the end-user.

All file-based views are looked up in the views folder.

Using ERB

ERB is written in pure Ruby and is included with the standard Sinatra distribution. ERB allows you to embed Ruby statements in an HTML page.

The important things to know about an .erb file is that <%= ruby_code %> evaluates the ruby code and outputs the result, and <% ruby_code %> evaluates the code, but doesn’t output anything.

We will use ERB for our app.

Note: If we write:

get '/' do
  erb :index
end

This tells Sinatra that when a GET request for ‘/’ comes in, that we should use the ERB helper to render the index.erb template, which is stored in the views sub-folder by convention and marked up with embedded Ruby (ERB).

Write the sinatragplus.rb app

Store sinatragplus.rb in the folder sinatragplus:

# sinatragplus.rb
require 'sinatra'
require 'google_plus'

error do
  erb :'500'
end

#class
class GPlus
  def initialize(apikey, gid)
    @apikey = apikey
    @gid = gid
    get_info
  end
  attr_reader :row0, :row1, :row2
  private
    #Get info about specific G+ ID
    def get_info
      # GooglePlus.api_key = 'Your API Key'
      begin
        GooglePlus.api_key = @apikey
        person = GooglePlus::Person.get(@gid.to_i)
        @row0 = person.display_name
        @row1 = person.tagline
        @row2 = person.url
      rescue Exception => msg
        # display the system generated error message
        puts msg
      end
    end
end

get '/' do
  erb :index
end

# Display Google+ details
post '/show' do
  @gplus = GPlus.new(params[:apikey], params[:gid])
  erb :show
end

Explanation

  • Install: gem install google_plus.
  • We are going to use the above installed google_plus gem.
  • To access the Google+ API, get your own Google API key.
  • Note down the Google+ ID of the person whose Google+ profile you want to display using this app. For example, here’s my Google+ URL and the number in the URL namely 107809992818057105754 is my Google+ ID.
  • When a GET request for ‘/’ comes in, we are going to render the index.erb template in the public/views folder.
  • The file index.erb has a HTML form that accepts the Google+ API key and ID for the user profile that you want to display. Note that even if you do not give any value to these fields, the app will not crash. Handler is the generic term that Sinatra uses for the “controllers”. A handler is the initial point of entry for new HTTP requests into your application. In handlers you can reach submitted form parameters directly via the params hash. Also note, that when you click on the submit button of the form a POST request is being sent.
  • The post '/show' do creates an object of our class GPlus passing to the initialize method the apikey and google id that your entered on the screen (via params). The initialize method in-turn calls a private method get_info that accesses the Google+ API and returns a person object We call the method display_name, tagline and url on the person object and populate instance variables @row0, @row1 and @row2.
  • The show.erb displays these values in a HTML table.

Error Handling

When someone comes to a page on your domain that is no longer there (either because it’s been deleted, because they’ve typed something in wrong or because the link that they followed was wrong) they are shown the dreaded 404 ‘page not found’ error page.

This error simply means that the person was able to communicate with your server but that the server couldn’t find the page that they were after.

404 errors should not be confused with “server not found” or similar errors, in which a connection to the destination server could not be made at all.

When a Sinatra::NotFound exception is raised, or the response’s status code is 404, the not_found handler is invoked:

Write 404.erb in the public/views folder. Note that I had to surround the erb :'404' in single quotes. This is because Ruby syntax doesn’t let symbol’s first character be a number. By quoting it, it gets around that issue.

A 500 error page will be thrown to the client when the Web server (running the Web Site) encounters an unexpected condition that prevents it from fulfilling the request by the client (e.g. your Web browser) for access to the requested URL.

By default error will catch Sinatra::ServerError. Sinatra will pass you the error via the ‘sinatra.error’ in request.env.

Write 500.erb in the public/views folder.

Our app is ready! Let’s deploy it to Heroku.

Create config.ru file in the folder sinatragplus

This file contains:

require './sinatragplus'
run Sinatra::Application

Install required gems for our app

In the Bash shell type:

$ bundle init

Edit the created Gemfile with your preferred text editor to let it look like this:

source "http://rubygems.org"
gem 'sinatra'
gem 'google_plus'

In the Bash shell type:

$ bundle check

Finally in the open Bash shell, type:

$ bundle install

Setup your local app to use Git

In the already open Bash shell, type:

$ git init
$ git add .
$ git commit -m "sinatragplus first commit"

Create the app on Heroku

In the bash shell, type:

$ heroku create

On my machine it showed:

Creating growing-fire-5252... done, stack is bamboo-mri-1.9.2
http://growing-fire-5252.heroku.com/ | git@heroku.com:growing-fire-5252.git
Git remote heroku added

Rename the app

$ heroku rename sinatragplus

Push your application to Heroku

$ git push heroku master

That’s it, the app is now running on Heroku! You can take a look at it, in your browser type: http://sinatragplus.heroku.com/.

What next?

On the person object use the attributes method to get all the person fields back as a Hash:

properties = person.attributes
properties.each { |key, value| puts "#{key} equals #{value}" }

Exercise

In show.erb I have populated only the display_name, tagline and url fields of person. Populate all the other person fields in the HTML table that is generated by show.erb.

Have fun!

Do post a link to your version of this program. Feel free to ask questions and give feedback in the comments section of this post. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning email me at satish [at] rubylearning.org

Technorati Tags: , , , ,

How do I run a Sinatra app using JRuby?

How do I run a Sinatra app using JRuby?

RubyLearning is conducting a free, online JRuby 101 course – the first of its kind, on Google+ Some participants wanted an answer to their question “How do I run a Sinatra app using JRuby?” This blog post explains the same. Read on.

Pre-requisite

I have a Windows XP box but the following should work on Mac and Linux-based computers too.

Ensure that you have already installed JDK 6, JRuby and set the relevant system environment variables path, classpath, JAVA_HOME and JRUBY_HOME.

Install Bundler

Bundler helps prevent conflicting or missing gems and shines when it’s time to configure those dependencies at install time and runtime.

JRuby comes with a fairly loaded standard library from scratch but that does not mean there aren’t other things you’ll need. Almost all of them are installable as Gems. RubyGems is the premier package management tool for Ruby. It works fine with JRuby and JRuby ships with it. You use it through the gem command. We will need to run the JRuby version of the gem command and to ensure that, we use the -S flag to the interpreter.

Create a project folder (say c:\jrubysinatra) on your hard-disk. Ensure that your internet connection is active. Now, open a command window in this project folder and type:

jruby -S gem install bundler

Note: This approach (jruby -S) works for any Ruby command-line tool, including gem, rake, spec, and others.

Create a Gemfile

Next, in your project folder, create a Gemfile. It looks something like this:

source "http://rubygems.org"
gem 'sinatra'

This Gemfile says a few things. First, it says that bundler should look for gems declared in the Gemfile at http://rubygems.org. You can declare multiple Rubygems sources, and bundler will look for gems in the order you declared the sources. Next, you will have to list all your applications dependencies in there. Sinatra’s direct dependencies (Rack and Tilt) will, however, be automatically fetched and added by Bundler.

To make bundler install the dependencies, in the already open command window, type:

jruby -S bundle install

Because all the gems in your Gemfile have dependencies of their own (and some of those have their own dependencies), running jruby -S bundle install on the Gemfile above, will install quite a few gems. If any of the needed gems are already installed, Bundler will use them. After installing any needed gems to your system, bundler writes a snapshot of all the gems and versions that it installed to Gemfile.lock.

Write your Sinatra app

Create the file hellojruby.rb in the folder c:\jrubysinatra.

require "rubygems"
require "bundler/setup"

require "sinatra"

get '/hi' do
    "Hello JRuby World!"
end

Set up your Sinatra application to use Bundler

For your Sinatra application, you will need to set up bundler before trying to require any gems. At the top of the first file that your application loads (for Sinatra, the file that calls require "sinatra"), put the following code:

require "rubygems"
require "bundler/setup"

This will automatically discover your Gemfile, and make all the gems in your Gemfile available to Ruby (in technical terms, it puts the gems “on the load path”). You can think of it as an adding some extra powers to require “rubygems”.

Now that your code is available to Ruby, you can require the gems that you need. For instance, you can require "sinatra".

Run your Sinatra application

In the already open command window, type:

jruby -S bundle exec jruby hellojruby.rb

In the command window, you will see:

== Sinatra/1.2.6 has taken the stage on 4567 for development with backup from WEBrick
[2011-09-03 07:21:17] INFO  WEBrick 1.3.1
[2011-09-03 07:21:17] INFO  ruby 1.8.7 (2011-08-23) [java]
[2011-09-03 07:21:17] INFO  WEBrick::HTTPServer#start: pid=5128 port=4567

Access the Sinatra application

In your browser, visit the URL: http://localhost:4567/hi – the browser shall display “Hello JRuby World!

That’s it for now.

Feel free to ask questions and give feedback in the comments section of this post. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning email me at satish [at] rubylearning.org

Technorati Tags: , , , ,

Performance Testing Rails Applications — How To?

Performance Testing Rails Applications — How To?

This guest post is by Gonçalo Silva, who is a full-time Ruby on Rails developer at escolinhas.pt and has participated in the Ruby Summer of Code 2010. He loves and contributes to many open-source projects, being a fan of Linux, Ruby and Android. He likes to call himself a hacker, but that’s just an excuse for being in front of the computer all the time. Oh, and he tweets at @goncalossilva.

Gonçalo Silva Rails 3.1 is just around the corner, and it brings enhanced performance testing tools. Let’s have a look at this often overlooked feature of our web application framework of choice.

This isn’t new

Rails has had built-in performance testing tools since version 2.2. Originally developed by Jeremy Kemper, these allowed developers to test the performance of their applications by writing integration tests which could be benchmarked and profiled under MRI. He later introduced two scripts – benchmarker and profiler – which were great to quickly benchmark or profile small snippets of code.

Actually, this is kind of new

I came across these tools during last year’s Ruby Summer of Code. I remember feeling astonished and bit ashamed about not having played with them before. I couldn’t use them at their full potential because of the lack of full support for YARV (or MRI 1.9), so I set off fixing that. While working on it, I’ve made a list of other things these tools lacked, that I wanted to implement after RSoC, namely: – Rubinius support – JRuby support – Test configurability – Decoupling benchmarker and profiler from RubyProf

Everything listed above is now implemented. Rails 3.1 will ship with these improvements and we’ll no longer have excuses for not using these great tools Rails provides for all of us.

Why you should care

The web should be fast. Response times are a key factor in user experience and there is very limited patience for slow websites. Ruby interpreters aren’t famous for being performant and our beloved framework isn’t known for getting faster with new releases. Nevertheless, we want our websites to be fast and responsive, and buying tons of hardware isn’t always an available choice – we need our code to be fast. We should care.

How does this work?

Rails’ performance testing tools allow you to quickly detect performance bottlenecks. As a rule of thumb, use benchmarking to detect the problem and then use profiling to understand it. Profiling provides in-depth information about your code and what it’s doing, but it lacks the speed and simplicity of benchmarking.

Patching your Ruby interpreter

You can skip this section if you’re a Rubinius/JRuby/REE user.

If you’re an MRI/YARV user, you’ll need a patched interpreter to access all available metrics. Before you run off, let me tell you that it’s very simple to install a patched Ruby interpreter nowadays. Thanks to Wayne, the author of RVM, all you need to do is to specify an additional flag when installing your interpreter, like this: rvm install 1.9.2 --patch gcdata Or, if you’re still using 1.8 (really?): rvm install 1.8.7 --patch ruby187gc

That’s all, folks. You now have a patched Ruby interpreter. If you want, you can have your patched interpreter side by side with your regular one, by simply assigning a name to it:

rvm install 1.9.2 --patch gcdata --name perf
rvm 1.9.2-perf  # my patched interpreter
rvm 1.9.2       # my regular interpreter

And that’s it.

Editing your Gemfile

You can skip this section if you’re using Rubinius/JRuby.

If you’re not, you’ll need to add RubyProf to your Gemfile:

gem 'ruby-prof', :git => 'git://github.com/wycats/ruby-prof.git'

Don’t forget to remove this from your Gemfile and re-run bundle install if you intend to switch to Rubinius or JRuby.

Performance tests

In order to use these tools, you’ll need to write performance tests. These tests are just like integration tests, except that the point is not to assert anything. They’ll just run the code that you want to see benchmarked/profiled.

Generating

As expected, Rails does this stuff for you. Just run:

script/rails generate performance_test example

And a new file will be placed in test/performance/example_test.rb containing the default test:

require 'test_helper'
require 'rails/performance_test_help'
class ExampleTest < ActionDispatch::PerformanceTest
  # Refer to the documentation for all available options
  # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
  #                          :output => 'tmp/performance', :formats => [:flat] }

  def test_homepage
    get '/'
  end
end
Editing

Since ActionDispatch::PerformanceTest inherits from ActionDispatch::IntegrationTest, you can use all available helpers for integration tests in your performance tests. For instance, if you wanted a test for your login action you could use:

class LoginTest < ActionDispatch::PerformanceTest
  fixtures :users
  self.profile_options = { :metrics => [:wall_time, :memory] }

  def test_login
    post_via_redirect "/login", :username => users(:youruser).username, :password => users(:youruser).password
  end
end
Tweaking

Starting with Rails 3.1, performance tests can be configured. As you’ve probably figured out from the aforeshown LoginTest, all you need to do is to specify an optional hash of options to use when benchmarking/profiling. You can use one set of options for each class. Not all options are available to all interpreters, especially the ones related with profiling. Metric/output availability for each interpreter will be shown below. You can skip this section and come back later, after grasping the whole concept. You’ll also be able to check it out on Rails’ performance testing guide once 3.1 comes out.

Metric availability
Benchmarking
Benchmarking
Profiling
Profiling
Output availability
Output availability
Running

Finally, it’s time to run your tests. Let’s start with benchmarking:

rake test:benchmark

And the output should be similar to this:

ExampleTest:
ExampleTest#test_homepage (16 ms warmup)
           wall_time: 0 ms
              memory: 17 KB
             objects: 195
             gc_runs: 0
             gc_time: 0 ms
 homepage (0.75s)

LoginTest:
LoginTest#test_login (92 ms warmup)
           wall_time: 10 ms
              memory: 180 KB
 login (0.44s)

Finished in 1.193759 seconds.

If any result disappoints you, profile it:

rake test:profile TEST=test/performance/login_test.rb

And you should get a similar output:

LoginTest:
LoginTest#test_login (105 ms warmup)
           wall_time: 69 ms
              memory: 2.4 KB
 login (5.02s)

Profiling will give you much more information than what’s printed on your terminal.

Reviewing results

By default, performance tests store their results in tmp/performance (although it can be changed by specifying a value for :output in the profile_options hash). For benchmarks, this is pretty straightforward: it stores one CSV per metric (LoginTest#test_login_memory.csv, for instance) with the results as time goes by.

measurement,created_at,app,rails,ruby,platform
183222,2011-08-10T18:15:09Z,,3.1.0.rc5,ruby-1.9.2.290,i686-linux
216344,2011-08-11T14:37:59Z,,3.1.0.rc5,ruby-1.9.2.290,i686-linux
(...)

When profiling, however, the result files are extremely important. They contain the juicy details of your test runs. Similarly to benchmarking results, there will be one file per metric. There are, however, multiple formats available, specially if you’re using RubyProf (and consequently MRI/REE/YARV). These formats can range from messy flat text files to awesome HTML stack traces, and they will provide valuable input when spotting bottlenecks.

The scope of this article is not to explore RubyProf’s available output formats, but you should have a look at the available printers. However, keep in mind that RubyProf supports more metrics and output formats than Rubinius/JRuby‘s profilers. These can only measure wall time when profiling, and will only print their results in Flat/Graph text formats.

RubyProf's HTML stack printer
RubyProf’s HTML stack printer

Quick tests

Performance tests are great, but they can be inconvenient when all you want is to quickly test a small snippet of code. For this, Rails provides two command line tools: benchmarker and profiler.

Open your terminal and run:

rails benchmarker 'User.all'

And it will work as if you had created a performance test and put that code in it. Very simple, right? Another example:

rails profiler 'User.all' 'User.find_by_login("goncalossilva")' --runs 3 --metrics cpu_time,memory # profiling memory won't work under Rubinius/JRuby (benchmarking memory will!)

Two things pop up from this code snippet: you can run multiple tests in a single command and you can specify options as you would with normal performance tests.

To get a glimpse at all available options, run:

rails benchmarker --help rails profiler --help

What can be done with this?

A lot of things can be accomplished with these tools. First and foremost, you can assess the performance of your application by benchmarking certain parts, either through tests or simple snippets of code. After finding potential bottlenecks, you can use profiling to gain a greater insight into what’s happening and how it can be improved.

There are other useful tasks that can be done with these tools. You could, for instance, compare the performance of different interpreters on your application:

    rvm 1.9.2
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm ree
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm rubinius
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm jruby
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory

Now you’ll know which interpreter takes less/more time/memory when it’s opening your homepage/running MyModel.slow_method.

Giving it a try

If you’ve come this far, now you know how to use these powerful tools. Try playing with them: I’m sure you’ll find valuable information about your applications’ performance, and potentially spot some easily fixable bottlenecks. With little effort, your application will be faster, you will be prouder and your users will be happier!

Feel free to ask questions and give feedback in the comments section of this post. Gonçalo has also written a guest blog post for RubyLearning before, titled – “Ruby gems — what, why and how“. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning write to satish [at] rubylearning.org

Technorati Tags: , ,

Top 3 Posts for July 2011 on RubyLearning

(Based on Google Analytics)

In case you missed them, here’s the roundup of the Top 3 posts for July 2011 on RubyLearning. Enjoy!

1. Throw, Catch, Raise, Rescue… I’m so confused!

Avdi Grimm explains the usage of Throw, Catch, Raise, Rescue in the Ruby programming language.

One of the aspects of Ruby that often confuses newbies coming from other languages is that it has both throw and catch and raise and rescue statements.

Read the rest of the article: Throw, Catch, Raise, Rescue… I’m so confused!.

2. How do I test my code with Minitest?

Steve Klabnik introduces the readers to Ruby’s minitest.

Ruby has fantastic tools that let you set up tests for your code that you can run automatically. You can save yourself tons of time and effort by letting the computer run thousands of tests every time you make a change to your code.

Read the rest of the article: How do I test my code with Minitest?.

3. Cryptography Or: How I Learned to Stop Worrying, and Love AES

Phillip Gawlowski explains how to use encryption and decryption in Ruby.

Ruby provides an API to OpenSSL, a well-tested, widely used library and set of tools used for encryption of all kinds, and includes its own implementations of several cryptographic hashes.

Read the rest of the article: Cryptography Or: How I Learned to Stop Worrying, and Love AES.

Your turn: Share the link to a roundup post you’ve written. If you’ve never written a roundup, try it this week. Be sure to share the link to your post here!

Technorati Tags: , ,

How do I test my code with Minitest?

How do I test my code with Minitest?

This guest post is by Steve Klabnik, who is a software craftsman, writer, and former startup CTO. Steve tries to keep his Ruby consulting hours down so that he can focus on maintaining Hackety Hack and being a core member of Team Shoes, as well as writing regularly for multiple blogs.

Steve Klabnik Programming is an interesting activity. Everyone has their favorite metaphor that really explains what programming means to them. Well, I have a few, but here’s one: Programming is all about automation. You’re really just getting the computer to automatically do work that you know how to do, but don’t want to do over and over again.

When I realized this, it made me look for other things that I do that could be automated. I don’t like repeating myself over and over and over again. That’s boring! Well, there’s one particular task that’s related to programming that’s easily made automatic, and that’s testing that your software works!

Does this story sound familiar? You run your program, try a few different inputs, check the outputs, and see that they’re right. Then, you make some changes in your code, and you’d like to see if they work or not, so you fire up Ruby and try those inputs again. That repetition should stick out. There has to be a better way.

Luckily, there is! Ruby has fantastic tools that let you set up tests for your code that you can run automatically. You can save yourself tons of time and effort by letting the computer run thousands of tests every time you make a change to your code. And it’ll never get tired and accidentally type in a 2 when you mean to type 3… Many people take this one step farther. They find testing so important and so helpful that they actually write the tests before they write the code! I won’t expound on the virtues of “test driven development” in this post, but it’s actually easier to write the tests first, once you get some practice at it. So, let’s pick a tiny bit of code to work on, and I’ll show you how to test it using Ruby’s built-in testing library, minitest.

For this exercise, let’s do something simple, so we can focus on the tests. We’ll make a Ruby class called CashRegister. It’ll have a bunch of features, but here’s the first two methods we’ll need:

  • The register will have a scan method that takes in a price, and records it.
  • The register will have a total method that shows the current total of all the prices that have been scanned so far.
  • If no prices have been scanned, the total should be zero.
  • The register will have a clear method that clears the register of all scanned items. The total should go back to zero again.

Seems simple, right? You might even know how to code this already. Sometimes, intermediate programmers practice coding problems that are easy, just to focus on how to write good tests, or to work on getting the perfect design. We call these kinds of problems ‘kata.’ It’s a martial arts thing.

Anyway, enough about all of this! Let’s dig in to minitest. It already comes with Ruby 1.9, but if you’re still using 1.8, you can install it with ‘gem install minitest.’ After doing so, open up a new file, register.rb, and put this in it:

require 'minitest/autorun'

class TestCashRegister < MiniTest::Unit::TestCase
  def setup
    @register = CashRegister.new
  end
  def test_default_is_zero
    assert_equal 0, @register.total
  end
end

Okay! There’s a lot going on here. Let’s take it line by line. On the first line, we have a ‘require.’ The autorun part of minispec includes everything you need to run your tests, automatically. All we need to do to run our tests is to type ruby register.rb, and they’ll run and check our code. But let’s look at the rest of the file before we do that. The next thing we do is set up a class that inherits from one of minitest’s base classes. That’s how minitest works, by running a series of TestCases. It also lets you group similar tests together, and split different ones up into multiple files.

Anyway, enough organizational stuff. In this class, we have two methods: the first is the setup method. This runs before each test, and allows us to prepare for the test we want to run. In this case, we want a new CashRegister each time, and we’ll store it in a variable. Now we don’t have to repeat our setup over and over again… it’s just automatic!

Finally, we get down to business, with the test_default_is_zero method. Minitest will run any method that starts with test_ as a test. In that method, we use the assert_equal method with two arguments. assert_equal is where it all happens, by comparing 0 to our register’s total, and it will complain if they’re not equal.

Okay, so we have our first test. Rock! You might be tempted to start implementing our CashRegister class, but wait! Let’s try running the tests first. We know they’ll fail, because we don’t even have a CashRegister yet! But if we run the tests before writing code, the error messages will tell us what we need to do next. The tests will guide us through the implementation of our class. So, as I mentioned earlier, we can run the tests by doing this:

$ ruby register.rb

We get this as output:

Loaded suite register
Started
E
Finished in 0.000853 seconds.

1) Error:
test_default_is_zero(TestRegister):
NameError: uninitialized constant TestRegister::CashRegister
register.rb:5:in `setup'

1 tests, 0 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 36463

Whoah! Okay, so you can see that we had one test, one error. Since we know classes are constants in Ruby, we know that the uninitialized constant error means we haven’t defined our class yet! So let’s do that. Go ahead and stick in an empty class at the bottom:

class CashRegister
end

And run the tests again. You should see this:

1) Error:
test_default_is_zero(TestRegister):
NoMethodError: undefined method `total' for #<CashRegister:0x00000101032a80>
register.rb:9:in `test_default_is_zero'

Progress! Now it says we don’t have a total method. So let’s define an empty one. Modify the class like this:

class CashRegister
  def total
  end
end

And run the tests again. Another failure:

1) Failure:
test_default_is_zero(TestRegister) [register.rb:9]:
Expected 0, not nil.

Okay! No more syntax errors, just the wrong result. Let’s keep it as simple as possible, and fill out a nice and easy total method:

def total
  0
end

Now, you may be saying, “Steve, that doesn’t calculate a total!” Well, you’re right. It doesn’t. But our tests aren’t yet asking to calculate a total, they’re just asking for a default. If we want a total, we should write a test that actually demonstrates adding it up. But we have fulfilled objective #3, so we’re doing good! Now, let’s work on objective #2, since we sorta feel like the total method is lying about what it’s supposed to do. In order to add up the items that were scanned, we need to scan them in the first place! Objective #1 says that this method should be called scan, so let’s write a test. Put it in your test class with the test_default_is_zero method:

def test_total_calculation
  @register.scan 1
  @register.scan 2
  assert_equal 3, @register.total
end

Make sense? We want to scan two things in, and then check that the total is correct. Let’s run our tests!

Loaded suite register
Started
.E
Finished in 0.000921 seconds.

1) Error:
test_total_calculation(TestRegister):
NoMethodError: undefined method `scan' for #<CashRegister:0x00000101031838>
register.rb:13:in `test_total_calculation'

2 tests, 1 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 54501

Okay! See that ‘.E’ up there? That graphically shows that we had one test passing, and one test with an error. Our first test still works, but our second is failing because we don’t have a scan method. Add an empty one to our CashRegister class, and run again:

1) Error:
test_total_calculation(TestRegister):
ArgumentError: wrong number of arguments (1 for 0)
register.rb:24:in `scan'
register.rb:13:in `test_total_calculation'

Whoops! It takes an argument. Let’s add that: def scan(price). Run the tests!

1) Failure:
test_total_calculation(TestRegister) [register.rb:15]:
Expected 3, not 0.

Okay! This sounds more like what we expected. Our total method just returns zero all the time! Let’s think about this for a minute. We need to have scan add the price to a list of scanned prices. So we’d better have it do that:

def scan(item)
  @items << item
end

But if you run the tests, you’ll see this:

1) Error:
test_total_calculation(TestRegister):
NoMethodError: undefined method `<<' for nil:NilClass
register.rb:25:in `scan'
register.rb:13:in `test_total_calculation'

Oops! @items is undefined. Let’s make it be an empty array, when we create our register:

def initialize
  @items = []
end

And run the tests:

1) Failure:
test_total_calculation(TestRegister) [register.rb:15]:
Expected 3, not 0.

Okay! We’re back to our original failure. But we’ve made some progress: now that we have an actual list of items, we’re in a position to make our total method work. Also, at each step, even though one test was failing, the other was still passing, so we know that we didn’t break our default functionality while we were working on getting a real total going.

Now, we’re in a better place to calculate the total:

def total
  @items.inject(0) {|sum, item| sum += item }
end

Or, if you want to make it even shorter:

def total
  @items.inject(0, &:+)
end

If you’re not familiar with Enumerable#inject, it takes a list of somethings and turns it into a single something by means of a function, in a block. So in this case, we can keep a running sum of all items, and then add the price of each one to the sum. Done! Run your tests:

Started
..
Finished in 0.000762 seconds.

2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

Woo hoo! We’re done! Our total can now be calculated. Great job!

Now, here’s a challenge, to see if you’ve really learned this stuff: write a test for a new method, clear, that clears the total. That’s objective #4 we talked about above.

Other parts of minitest

This has been a mini intro to minitest and using it to test your code. There are other methods in the assert family, too, like assert_match, which takes a regular expression and tries to match it against something. There’s the refute family of tests, which are the opposite of assert:

assert true #=> pass
refute true #=> fail

There are also other tools that make minitest useful, like mocks, benchmark tests, and the RSpec-style ‘spec’ syntax. Those will have to wait until later! If you’d like to learn about them now, check out the source code on GitHub.

Happy testing!

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Also, do check out Steve’s other article: “How do I keep multiple Ruby projects separate?” on RubyLearning. Thanks!

Technorati Tags: , ,

Cryptography Or: How I Learned to Stop Worrying, and Love AES

Cryptography Or: How I Learned to Stop Worrying, and Love AES

This guest post is by Phillip Gawlowski, who is living in the German wilderness of Oberberg near Cologne. Phillip spends his time writing Ruby as a hobby just for fun. He tries to make life a little easier for himself and for others when he is crazy enough to release his code as open source. He’s neither famous nor rich, but likes it that way (most of the time). He blogs his musings at his blog.

Phillip Gawlowski A friend gave you the plans for Dr. Blofeld’s newest Doomsday Device. Over the engine noise of his Aston-Martin, he tells you: “Send this to offers@universal-exports.co.uk, and make sure it arrives there intact!”

All you have is a laptop, wonky Internet access, and Ruby. What to do?

AES For Safety, SHA2 For Integrity

You now have two goals:

  1. Make the Doomsday Device plans unreadable, and
  2. Ensure that the data has arrived at its destination without error.

Fortunately, Ruby provides an API to OpenSSL, a well-tested, widely used library and set of tools used for encryption of all kinds, and includes its own implementations of several cryptographic hashes.

In this article we will use AES for de- and encryption, and SHA2 to hash data.

Using SHA2

Like many things, Ruby makes creating crypto-hashes easy:

require 'digest/sha2'
sha256 = Digest::SHA2.new(256)
sha256.digest("Bond, James Bond")

The SHA2#new call provides us with the bit length we want our hash to have. SHA2 exists in two variants: 256, also called SHA256, and 512, called SHA512. A longer key length takes longer to calculate, but is also more accurate, and much more difficult to attack with a rainbow table or other cryptanalysis.

Once we have our SHA object, we pass a String of data into the #digest to have the hash of this data returned as a String.

You can call the #digest method directly when you are working with MD5 or SHA1:

require 'digest/MD5'
Digest::MD5.digest "Bond, James Bond"

The Advanced Encryption Standard

Theory

As AES is a so-called symmetric-key block cipher, it operates on chunks of data, called blocks, and applies the provided key to this block to create de- and encrypted output. The use of the same key for encryption and decryption is what makes the cipher symmetric. Conversely, asymmetrical ciphers use different keys for decryption and encryption, usually a private key known only to the recipient to decrypt, and a public key known to anyone to encrypt. SSH, SSL/TLS and PGP are examples for this kind of cipher.

The AES family has three modes of operation: 128 bit, 192 bit, and 256 bit. Just as with SHA2, you’ll find AES-128, or AES-256 being used to describe the particular block size that can be used.

The downside to this approach is that the same key is used for each block of data, which weakens the encryption (the same data is encrypted in the same way!). The solution is to use a so called “mode of operation”, which scrambles the cipher so that it becomes indistinguishable from noise.

A full discussion of methods of operation and their strengths and weaknesses would go well beyond the scope of this article, however.

…And Practice

Now let’s take a look at Ruby’s encryption API:

require 'openssl'
require 'digest/sha2'

payload = "Plans for Blofeld's newest Doomsday Device. This is top secret!"
sha256 = Digest::SHA2.new(256)
aes = OpenSSL::Cipher.new("AES-256-CFB")
iv = rand.to_s
key = sha256.digest("Bond, James Bond")

aes.encrypt
aes.key = key
aes.iv = iv
encrypted_data = aes.update(payload) + aes.final

puts encrypted_data

Since Ruby’s OpenSSL API is pretty straight forward (and so is the OpenSSL API, if you would like to use OpenSSL in C code), we will only discuss what’s really important.

OpenSSL::Cipher.new("AES-256-CFB") sets up an AES object, with a block size of 256 bits and the CFB mode of operation. To find out which ciphers are supported, OpenSSL::Cipher.ciphers allows you to interrogate the class for which ciphers are understood.

The iv variable stores our random Initialization Vector, random data to seed the mode of operation to ensure that each 256 bit block is encrypted uniquely, and thus (hopefully) indistinguishable from noise.

We also take advantage of SHA2′s 356 bit variant to generate a 256 bit password from a simpler password. AES expects the encryption key to be as long as a block of data, and since creating a 256 bit password from hand is pretty difficult, we let the computer do the job. When used in production, you most likely want to add a salt to the hash, or use a user’s already hashed password.

With the #decrypt and #encrypt methods, we put our AES object into the proper state. Behind the scenes, this initializes OpenSSL’s encryption engine. These two method calls are required before any other method call!

Last but definitely not least, the #update and #final methods are where the encryption actually happens. The more data you have, the longer the chunks, and the more complex the cipher, the longer this will take. The #final method does the same as #update, but ads padding to a chunk to bring it up to the required block size.

In case you make a mistake, or want to do another round of encryption or decryption, the #reset method can reset a Cipher object.

Decryption works pretty much the same as encryption, except that we pass the encrypted data to the #update-method:

aes.decrypt
aes.key = key
aes.iv = iv
puts aes.update(encrypted) + aes.final

Note, however, that both the key and the IV must be the same, and thus have to be stored or transmitted to the recipient of the encrypted data!

Verifying Integrity

As we’ve already seen, a hashing algorithm can turn data of arbitrary length into a fixed length, unique stream of bytes. This can function as password storage, to generate securer keys for encryption, or, since the output of a hash algorithm is deterministic (it’s always the same for the same input) as an integrity check.

If you’ve downloaded a Linux distribution or other software, you have already seen this, in the form of MD5 digests, with which you can verify that a download is complete and error free, like on Ruby’s homepage.

We will do the same with our encrypted data, as a poor man’s message authentication code–a technique in cryptography to ensure that a message has not been tampered with:

poor_mans_mac = sha2.digest(encrypted)

Now all that’s left is to send an email to James’ employer with the Doomsday Device plans, and to give them a call to give them the IV and key.

Closing Remarks

Think of the Future

Security is not a state, it is a process. You should write your security-aware code in such a way that you don’t depend on a particular cryptographic algorithm. Ruby’s API (and OpenSSL’s own API) wrap encryption abstractly, so that you can swap out the algorithm you use at any time. This is also necessary for hashing algorithms: While there are no feasible attacks against SHA2 yet, the cryptanalysis only gets better over time, as the histories of MD5 and DES show.

Schneier’s Law

Schneier’s Law states that “any person can invent a security system so clever that she or he can’t think of how to break it.” This is why Ruby’s developers use OpenSSL to do encryption, a widely tested and certified (in some variants!) cryptographic library, instead of writing their own library.

A mistake in your implementation can compromise your and your customer’s data, since so called “side channel attack” are used as a matter of course to attack cryptography.

Encryption Does Not Mean You Are Safe

It is important, and I cannot stress this enough, that you do not store encrypted data and the keys to access it on the same machine (ideally, you don’t store these things on the same network!), or do your encryption and decryption on the same machine that you store you encrypted data on. Whole libraries have been filled with books on how to design a secure system, from hardware to software. Above all, security is a mindset, and you have to be properly paranoid to secure your data and access to this data. Sooner or later, if you deploy, or are about to deploy, security relevant code have your code tested by outsiders. Penetration testing is worth your while.

Asymmetric encryption has been invented to solve one problem with encryption: It is not necessary for such a cipher to transmit the key. However, they have their own set of trade offs (key trust, and computational efficiency, among others).

The Safest Data is No Data

Like the fastest code is no code at all, if you don’t store data you don’t absolutely, positively have to store, don’t even bother with it. What you don’t have can’t be compromised.

Conclusion

This article is nothing but a superficial introduction to encryption in Ruby. There are dozens of standards and regulations that govern this vast topic. However, I have tried my best to give you, fellow Rubyists, enough knowledge about this topic for you to know which questions you should ask, which is, in the end, much more important than the code itself. Now go forth, and hash an encrypt and decrypt, and, above all, have fun doing it!

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Technorati Tags: , ,

Throw, Catch, Raise, Rescue… I’m so confused!

Throw, Catch, Raise, Rescue… I’m so confused!

This guest post is by Avdi Grimm, who is the author of “Exceptional Ruby“, an in-depth guide to exceptions and failure handling in Ruby. RubyLearning readers can get a $3 discount on the book by using code RUBYLEARN. Avdi has been hacking Ruby code for 10 years, and is still loving it. He is chief aeronaut at ShipRise, a consultancy specializing in sustainable software development and in helping geographically dispersed teams work more effectively. He lives in southern Pennsylvania with his wife and four children, and in his copious spare time blogs and podcasts at Virtuous Code and WideTeams.com.

Old keywords, new meanings

Avdi Grimm One of the aspects of Ruby that often confuses newbies coming from other languages is the fact that it has both throw and catch and raise and rescue statements. In this article I’ll try and clear up that confusion.

If you’re familiar with Java, C#, PHP, or C++, you are probably used to using try, catch, and throw for exception handling. You use try to delineate the block in which you expect an exception may occur. You use catch to specify what to do when an exception is raised. And you use throw to raise an exception yourself.

You’ve probably noticed that Ruby has throw and catch… but they don’t seem to be used the way you’re used to in other languages! And there are also these “begin“, “raise” and “rescue” statements that seem to do the same thing. What’s going on here?

Getting out fast

If you’ve done much programming in another language like Java, you may have noticed that exceptions are sometimes used for non-error situations. “exceptions for control flow” is a technique developers sometimes turn to when they want an “early escape” from a particular path of execution.

For instance, imagine some code that scrapes a series of web pages, looking for one that contains a particular text string.

def show_rank_for(target, query)
  rank = nil
  each_google_result_page(query, 6) do |page, page_index|
    each_google_result(page) do |result, result_index|
      if result.text.include?(target)
        rank = (page_index * 10) + result_index
      end
    end
  end
  puts "#{target} is ranked #{rank} for search '#{query}'"
end

show_rank_for("avdi.org", "nonesuch")

(For brevity, I’ve excluded the definitions of the #each_google_result_page and #each_google_result methods. You can view the full source at https://gist.github.com/1075364.)

Fetching pages and parsing them is time-consuming. What if the target text is found on page 2? This code will keep right on going until it hits the max number of result pages (here specified as 6).

It would be nice if we could end the search as soon as we find a matching result. We might think to use the break keyword, which “breaks out” of a loop’s execution. But break only breaks out of the immediately surrounding loop, and here we have a loop inside another loop.

This is a situation where we might come up with the idea of using an exception to break out of the two levels of looping. But exceptions are supposed to be for unexpected failures, and finding the results we were looking for is neither unexpected, nor a failure! What to do?

Throwing Ruby a fast ball

Ruby has given us a tool for just this situation. Unlike in other languages, Ruby’s throw and catch are not used for exceptions. Instead, they provide a way to terminate execution early when no further work is needed. Their behavior is very similar to that of exceptions, but they are intended for very different situations.

Let’s look at how we can use catch and throw to end the web search as soon as we find a result:

def show_rank_for(target, query)
  rank = catch(:rank) {
    each_google_result_page(query, 6) do |page, page_index|
      each_google_result(page) do |result, result_index|
        if result.text.include?(target)
          throw :rank, (page_index * 10) + result_index
        end
      end
    end
    "<not found>"
  }
  puts "#{target} is ranked #{rank} for search '#{query}'"
end

This time we’ve wrapped the whole search in a catch{...} block. We tell the catch block what symbol to catch, in this case :rank. When the result we are looking for is found, instead of setting a variable we throw the symbol :rank. We also give throw a second parameter, the search result :rank. This second parameter is the throw’s “payload”.

The throw “throws” execution up to the catch block, breaking out of all the intervening blocks and method calls. Because we gave the throw and catch the same symbol (:rank), the catch block is matched to the throw and the thrown symbol is “caught”.

The rank value that we gave as a payload to throw now becomes the return value of the catch block. We assign the result value to a variable, and proceed normally.

What if the search string is never found, and throw is never called? In that case, the loops will finish, and the return value of the catch block will be the value of the last statement in the block. We provide a default value (“<not found>”) for just this possibility.

catch and throw in the real world

The Rack and Sinatra projects provide a great example of how throw and catch can be used to terminate execution early. Sinatra’s #last_modified method looks at the HTTP headers supplied by the client and, if they indicate the client already has the most recent version of the page, immediately ends the action and returns a “Not modified” code. Any expensive processing that would have been incurred by executing the full action is avoided.

get '/foo' do
  last_modified some_timestamp
  # ...expensive GET logic...
end

Here’s a simplified version of the #last_modified implementation. Note that it throws the :halt symbol. Rack catches this symbol, and uses the supplied response to immediately reply to the HTTP client. This works no matter how many levels deep in method calls the throw was invoked.

def last_modified(time)
  response['Last-Modified'] = time
  if request.env['HTTP_IF_MODIFIED_SINCE'] > time
    throw :halt, response
  end
end

The way Rack uses catch/throw illustrates an important point: the throw call does not have to be in the same method as the catch block.

Conclusion

Ruby is a language that tries to anticipate your needs as a programmer. One common need is a way to terminate execution early when we find there is no further work to be done. Unlike in some languages, where we would have to either abuse the exception mechanism or use multiple loop breaks and method returns to achieve the same effect, Ruby provides us with the catch and throw mechanism to quickly and cleanly make an early escape. This leaves begin/raise/rescue free to be used for errors, and nothing else.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Technorati Tags: , ,