Ruby Shortcuts

April 10th, 2013 15:15 – by Torsten Trautwein

Symbol to_proc

Especially when chaining together methods like collect, select, map, etc. using the symbol as a shorthand for a block, can be very useful:

class Character
  attr_accessor :name, :actor

  def initialize(opts = {})
    @name, @actor = opts[:name], opts[:actor]
  end
end

jack = Character.new(name: 'Jack Shepard', actor: 'Matthew Fox')
kate = Character.new(name: 'Kate Austen', actor: 'Evangeline Lilly')
hurley = Character.new(name: 'Hugo Reyes', actor: 'Jorge Garcia')
sayid = Character.new(name: 'Sayid Jarrah', actor: 'Naveen Andrews')
sun = Character.new(name: 'Sun-Hwa Kwon', actor: 'Yunjin Kim')
aaron = Character.new(name: 'Aaron Littleton', actor: 'William Blanchette')

oceanic_six = [jack, kate, hurley, sayid, sun, aaron]

oceanic_six.collect { |c| c.name }.map{ |c| c.downcase }.last
=> "aaron littleton"

oceanic_six.collect(&:name).map(&:downcase).last
=> "aaron littleton"

Lambda

Since Ruby 1.9, you can use -> instead of lambda. This of course also holds true for arguments, though the syntax changes a little:

old_l = lambda { |x| x+19 }
new_l = -> x { x+19 }

old_l.call(23)
=> 42

new_l.call(23)
=> 42

Presence

The presence method is Rails specific, but nevertheless improves readability by a fair amount:

something = 'something'
anything = (something && something.present?) ? something : 'default'
=> "something"
anything = something.presence || 'default'
=> "something"

something = nil
anything = (something && something.present?) ? something : 'default'
=> "default"
anything = something.presence || 'default'
=> "default"

Improve your Git commits using patch mode

November 11th, 2012 22:56 – by Torsten Trautwein

When modifying existing code, it's often the case the I stumble upon some other part nearby that seems like it could use some improvement. To keep the commit history clean and more accurate, I could keep that part in mind, finish the changes I originally wanted to do, commit, make the refinements I came across by chance and then commit those.

But let's face it, I don't. Mostly, I just add a commit message the reads like this:

changed x, improved y

And sometimes not even that. So how to improve this without switching between the editor and the console all the time?

Introducing the patch mode

Luckily, Git has a switch ready for exactly that case.

Let's assume we have the following piece of code:

#!/usr/bin/ruby
presidents = ["Jimmy Carter", "Ronald Reagan", "George H. W. Bush", "Bill Clinton", "George W. Bush", "Barack Obama"]
presidents.each do |president|
  puts president
end

vice_presidents = ["Walter Mondale", "George H. W. Bush", "Dan Quayle", "Al Gore", "Dick Cheney", "Joe Biden"]
vice_presidents.each do |vice_president|
  puts vice_president
end

We now want to change George H. W. Bush to George Bush Sr. and George W. Bush to George Bush Jr.. Easy enough.

#!/usr/bin/ruby

presidents = ["Jimmy Carter", "Ronald Reagan", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
presidents.each do |president|
  puts president
end

vice_presidents = ["Walter Mondale", "George H. W. Bush", "Dan Quayle", "Al Gore", "Dick Cheney", "Joe Biden"]
vice_presidents.each do |vice_president|
  puts vice_president
end

While doing so, we think it would be a nice addition to also have an output of all the presidents that are still alive. So we add the following lines to the same file.

living_presidents = ["Jimmy Carter", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
living_presidents.each do |living_president|
  puts living_president
end

So in the end we changed some of the file, but also added a part that hasn't got so much to do with that change.

We end up with this:

#!/usr/bin/ruby

presidents = ["Jimmy Carter", "Ronald Reagan", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
presidents.each do |president|
  puts president
end

vice_presidents = ["Walter Mondale", "George H. W. Bush", "Dan Quayle", "Al Gore", "Dick Cheney", "Joe Biden"]
vice_presidents.each do |vice_president|
  puts vice_president
end

living_presidents = ["Jimmy Carter", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
living_presidents.each do |living_president|
  puts living_president
end

We could just type git commit -m"changed the presidents names for better perceptibility and added an output for the currently living presidents" but now we know better.

So let's use Git's patch mode by using git commit -p which seperates the changes in hunks and lets us choose which are tied together logically.

% git commit -p 
diff --git a/example.rb b/example.rb
index 1ade9f3..b5f56a2 100755
--- a/example.rb
+++ b/example.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/ruby

-presidents = ["Jimmy Carter", "Ronald Reagan", "George H. W. Bush", "Bill Clinton", "George W. Bush", "Barack Obama"]
+presidents = ["Jimmy Carter", "Ronald Reagan", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
 presidents.each do |president|
   puts president
 end
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?

This is the first part and we'd really like to stage that for commit. So we type y.

Next, Git asks us if we'd also like to stage the following part for commit.

@@ -9,3 +9,8 @@ vice_presidents = ["Walter Mondale", "George H. W. Bush", "Dan Quayle", "Al Gore
 vice_presidents.each do |vice_president|
   puts vice_president
 end
+
+living_presidents = ["Jimmy Carter", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
+living_presidents.each do |living_president|
+  puts living_president
+end
Stage this hunk [y,n,q,a,d,/,K,g,e,?]?

But since we don't want this in the same commit, we type n this time. We then get asked for the commit message as usual.

Now, we type git commit -p again and are asked if we want to stage the following part for commit, once again:

% git commit -p                                              
diff --git a/example.rb b/example.rb
index 5854cd9..b5f56a2 100755
--- a/example.rb
+++ b/example.rb
@@ -9,3 +9,8 @@ vice_presidents = ["Walter Mondale", "George H. W. Bush", "Dan Quayle", "Al Gore
 vice_presidents.each do |vice_president|
   puts vice_president
 end
+
  +living_presidents = ["Jimmy Carter", "George Bush Sr.", "Bill Clinton", "George Bush Jr.", "Barack Obama"]
+living_presidents.each do |living_president|
+  puts living_president
+end
Stage this hunk [y,n,q,a,d,/,e,?]?

This time, we do want it staged. So we type y, type in the commit message and we're good to go.

Once someone else (or we ourselves) come across that code again, we're have better chances to find the change we're looking for in the file's history without searching around the file(s) and wondering what those changes have to do with the commit message.

% git log
commit 16584466b7a2a6098602bf3014af80d94e13fe6f
Author: Torsten Trautwein <mail@example.com>
Date:   Sun Nov 11 16:31:08 2012 +0100

    output of the presidents currently alive

commit 7f9d163374d9cb30903d56b2cdb52a549d82ac52
Author: Torsten Trautwein <mail@example.com>
Date:   Sun Nov 11 16:27:16 2012 +0100

    changed the presidents names for better perceptibility

As you can see, the commit log is uncluttered and well structured and we didn't really have to do much for it.

If you are looking for more information on Git, have a look at Version Control with Git by Jon Loeliger and Matthew McCullough.

Update

As mentioned by languagehacker in the comments over at hn, you can also use patch mode to add hunks (think git add -p) which allows you to review them before committing.

Markdown 101

November 3rd, 2012 21:56 – by Torsten Trautwein

Markdown is awesome. Basically, it provides a new syntax for the most frequently used html tags that's easy to read and write. This syntax can then be interpreted e.g. by your blog software and converted to html for a browser to display.

If you write texts that will be published online, you should consider using it. It's clean, lightweight, easy to learn, and a great way to speed up your workflow.

So let's see how it works:

Headers

H1 headers can be defined by underlining them with equal signs.

Some Words
==========

H2 headers can be defined by underlining them with hyphens.

Something Else
--------------

H3 headers and so on – as well as H1 and H2 – are defined by the number of hash signs in front and at the end of a line.

### Another Title ###

Emphasis

Encapsulating something in single asterisks makes it italic.

*Italic Text*

Do the same with two asterisks makes it bold.

**Bold Words**

Lists

Unordered lists use asterisks, pluses or hyphens.

* An Item
* Another One
* One More

Ordered lists use numbers followed by periods.

1. First Step
2. Second Step
3. ???
4. Profit

Links

Links are represented by a description in square brackets followed by the url in round brackets.

[some text](http://example.com)

Markdown has a lot more to offer; please visit Daring Fireball for all the details.

Get In Touch

The usual channels

twitter @neowork
Google+ +neowork
github neowork
500px neowork
E-Mail mail@neowork.com

Or send a message right away

captcha

Imprint

Torsten Trautwein
Pfannmuellerstr. 28
60488 Frankfurt am Main, Germany

mail@neowork.com
+49 (0)7000 NEOWORK
+49 (0)7000 63 69 675
max. 0.12 €/min on German landlines