Programming ≈ Fun

Small Sample of Ruby Elegance

| Comments

If you don’t know Ruby please take a few moments and look at code below. You may like it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
w = %w[a c d b e] # same as w = ["a", "c", "d", "b", "e"]
w.sort #=> ["a", "b", "c", "d", "e"]
w.sort.reverse #=> ["e", "d", "c", "b", "a"]
w.sort { |a,b| b<=>a } #=> ["e", "d", "c", "b", "a"]

w.reduce(:+) #=> "acdbe"
w.map(&:upcase) #=> ["A", "C", "D", "B", "E"]

w.include? "a" #=> true

(1..8).select(&:even?) #=> [2, 4, 6, 8]
(1..8).reject(&:even?) #=> [1, 3, 5, 7]

langs = %w[ruby python perl] # same as langs = ["ruby", "python", "perl"]

langs.group_by(&:chr) #=> {"r"=>["ruby"], "p"=>["python", "perl"]}
langs.map(&:capitalize) #=> ["Ruby", "Python", "Perl"]

As they say:

The beauty of Ruby is found in its balance between simplicity and power.

If after this your mouth is watering, you can try Ruby online.

Quality Is Overrated

| Comments

I’ve been a TDD zealot for the last 7-8 years. I take pride in my code being well tested, my solutions being user friendly and my design being test driven.

When I test I know my system works. I sleep like a baby. I have a balls of brass. I can embrace change and laugh at how easy it is to add new requirements.

The thing is, in my life I’ve seen a fair amount of big systems that are terrible. They all have one thing in common. Everybody hates them. Programmers, users… but they do work, sort of. They are slow and buggy but nevertheless they deliver some value to the users.

Enterprise is euphemism for lame systems that barely work for 300 users?

Oddly, in many of those terrible systems funny thing happened. After a while guess what? People involved (users and programmers) made those terrible systems work (just enough) and all of a sudden you have a winner. Bigger the system, bigger the win. Bigger the mess, bigger the ecosystem of additional companies making it all work.

Think Windows & antivirus for example.

I wonder how smug IBM felt when developing OS/2 with all the cool stuff…and than a big nothing happened. Right now you might be thinking that I’ve lost it. You are ready to click away… but let see some examples:

Blow Your Mind (Maybe) With Case Equality in Ruby

It all starts with “A Little Unnecessary Smalltalk Envy” from Bob Hutchinson.

Quick warning: If you don’t like monkey patching… Run away now it is still not too late…

1
2
3
4
5
6
7
8
9
10
11
12
# Copied from
# http://blog.teksol.info/2007/11/23/a-little-smalltalk-in-ruby-if_nil-and-if_not_nil
# http://recursive.ca/hutch/2007/11/22/a-little-unnecessary-smalltalk-envy/
# Bob Huntchison
# Shortened to just support if_not_nil
class Object
  def if_not_nil(&block) yield(self) if block end
end

class NilClass
  def if_not_nil(&block) end
end

This enables you to stop treating nil as a special case:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

def person_that_exists
  Person.new("drKreso")
end

def non_existing_person
  nil
end

person_that_exists.if_not_nil { |person| puts "found #{person.name}"} # => found drKreso
non_existing_person.if_not_nil { |person| puts "found #{person.name}"} # => nothing happens

Refactoring My Basement

A rather unfortunate series of events led me ending up in my basement with a task of cleaning it up. It was mildly put a mess, this photo was taken shortly after refactoring has begun. I was unable to even go inside and therefore forced to put half of the stuff in the hall.

Faking Multiple Blocks in Ruby

| Comments

Three months ago I was comparing Lisp, Smalltalk and Ruby. I was struggling to create new language syntax (for example my version of if..else) that is so easy to do in Lisp, and also possible in Smalltalk:

In Smalltalk it would be used like this:

1
2
3
(1 = 1)
    ifCorrect:    [Transcript show: 'I am correct']
    ifNotCorrect: [Transcript show: 'I am wrong'].
My knowledge of Smalltalk is non-existing, but look at the beautiful [] block syntax and notice the keyword arguments being able to accept multiple blocks.

Implementation in Smalltalk is both straightforward and cool:

1
2
3
4
5
6
7
# this is in True class
ifCorrect: trueAlternativeBlock ifNotCorrect: falseAlternativeBlock
     ^trueAlternativeBlock value

# this is in False class
ifCorrect: trueAlternativeBlock ifNotCorrect: falseAlternativeBlock
     ^falseAlternativeBlock value

In Ruby I was missing the ability to have multiple blocks in method call that would enable me to evaluate only one leg. This was best I could come up with and it included (mis)using the lambdas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class FalseClass
  def if_correct(trueBlock, hash)
    hash[:if_not_correct].call
  end
end

class TrueClass
  def if_correct(trueBlock, hash)
    trueBlock.call
  end
end

(1==0).if_correct ->{ print "Hooray it's true"},
       if_not_correct:->{print "Not true"}

Today I’ve read the excellent post about using Ruby Blocks as Dynamic Callbacks. I was mesmerized, but of course I didn’t get it. Than I saw really kick ass explanation here. Holding hands did have effect even on me. Still I am not sure that I would be able to pull it of on my own without watching the original code. At the end I did saw one gist in comments claiming to have similar pattern. I don’t know if it’s better, but it looks less intrusive because there is no patching of Proc class and it clicked more easily.

Decorators in Ruby

| Comments

The decorator pattern is used to extend the functionality of a certain object in a runtime. In a statically typed language you need to define decorator interface, then subclass from it and initialize the component (object) that you are decorating.

In Ruby you can pledge: “Yes I am a grownup” and skip the formal interface definition part.

In either case the payoff comes with the fact that you can combine “extensions” without writing out complex inheritance tree that accounts for all possible combinations. Therefore you end up using extension that you need when you need them.

Let’s check it out on Wikipedia coffee example.

1
2
3
4
5
6
7
8
class Coffee
  def cost
    1
  end
  def ingredients
    %w(coffee water sugar)
  end
end

If we want some latte, we can create a new decorator for the coffee:

1
2
3
4
5
6
7
8
9
10
11
class Latte
  def initialize(component)
    @component = component
  end
  def cost
    @component.cost * 1.2
  end
  def ingredients
    @component.ingredients << "milk" << "whipped cream" << "vanilla"
  end
end

Favorite Vim Tools & Tricks

| Comments

I’ve been using Vim for the last two years. It did take some getting use to, but the idea clicked almost instantly. Having normal and insert mode is superior concept in my mind. It allows you to treat text editing as a game.

I am not a power user by far but I do have some favorite tricks.

Using console version

  • Pros:
    • Console output is colored
    • Ctrl-y puts you to console, fg puts you right back
    • No need to open console in another window
  • Cons:
    • Color scheme is a bit uglier (less color in console)
    • Copy paste is a bit harder (from other GNOME apps, at least for me)

I’ve tried everything here. Rationally I thought that the console version is too ugly. BUT I noticed that I type vim from terminal unconsciously. The Ctr-y/fg combo and ability to start test to console from within vim sealed the deal. Somehow I got use to lack of prettier color scheme.

Mocking and Stubbing on Tiny Example

| Comments

Guard Clause

If you know what test doubles are. If you know that stub gives canned answers and that mock is an object that you can set expectations on… Pass along. If you are still uncertain about this you may want to read on.

Stubs

Chances are (if you are a guy) that you are using stub when talking to your girlfriend:

Does my ass look big in this jeans? No!

It doesn’t matter what the real answer is, you just give back the prepared one. Kinda like when you need certain data for your tests. You shove in your answer for example 11/28/2011 and you expect the canned answer every time. It’s a lie agreed upon for the greater cause.

Mocks

Mock is emotionally ‘complicated’ stub. He also gives back canned answers but he expects certain things to be done in the process to be fully satisfied. Translated to our girlfriend example it is something like this:

Are you cheating on me? No!

Here the expectation is that you don’t give answer right away, because it looks canned that way. Also you shouldn’t think to long before answering. Mocked object v2.0 might expect that you look her in the eyes…

DRY me is noticing that we have overlapping in code, so I would probably use the same algorithm for both question in the class BlowTheTruthOutOfWaterIfItsBrutal.

JIRA Worklog From Command Line

| Comments

If you are using JIRA to log your working hours I think the best policy is to write it right after you are done with particular task. In the process I’ve experienced a couple of non-happy-path-scenarios such as:

  1. JIRA is down
  2. JIRA is slow (I am complicated about speed, kinda like Corey Haines)

In order to mitigate that, I’ve started writing notes to .txt file. I would then type-in all hours at the end of the day. It’s just me and my beloved Vim. What could go wrong? Right?

Well, it sounded better in theory as it had its own share of problems, such as:

  1. Keeping the file open all day long (and more so finding it)
  2. Forcing myself to fiddle with JIRA for x tasks (not to mention “at the end of the day” part)

Downcase for UTF-8 Characters in Ruby

| Comments

There is one gotcha in Ruby UTF-8 support.

String method downcase is local insensitive, meaning it ignores UTF-8 characters not in standard ASCII character set.

Example below will give you expected results:

1
2
3
"HELLO”.downcase 

-->hello

Next example will not behave as desired as non standard characters remain in uppercase:

1
2
3
"DINING ROOM - SALLE À MANGER".downcase

-->dining room - salle À manger

It is supposed to be fixed in Ruby 2.0. Until then you’ll need some monkey patching:

1
gem install unicode
1
2
3
4
5
6
7
8
9
#enviroment.rb
require 'unicode'
require 'lib/string'
#lib/string.rb
class String
  def downcase
    Unicode::downcase(self)
  end
end

Risky business, I know. But it’s the only only solution that I know of.