A Developer with a Pencil

An Open Letter: Internet, Lighten Up

Yesterday, something terrible happened.

Me and a group of dev-friends were working a few months ago on a private project in ruby, a simple state machine implementation that was hosted as a private repository on Github. A few days ago one of my friends came to me and asked to use this project - so I opened it to public access.

Well, I really didn’t see it coming.

First let me say, I do not - under any circumstances agree or endorsed such behavior either in code or in the real world - but part of the test code for that repo included mentions of the words “gay” and “gangrape” in conjunction.

It was first brought to my attention on Twitter - I immediately went to the code and shamefully removed the offensive file and added a sorry note to the readme file. I also published a quick tweet explaining how sorry I was and that no matter how funny it was in our inner developer circle (yes, including a homosexual with a sense of humor) it shouldn’t have crossed the line into the Internet public highway.

The tweet mentioned above caused an immediate avalanche that headed straight at me, by people that were focusing entirely on how offensive this code was, but disregarded the fact that I admitted in a mistake, promised to make sure it wouldn’t happen again - and published 2 (!!!) public messages on being the down bottom ashamed that I am.

Yes. It is almost inexcusable. But things should be put in perspective.

Not every time someone makes a bad decision, a mistake or even something awful like we did - deserves an immediate attack and a righteous stampede.

The Internet and the open-source communities are FULL of naming conventions that are offensive and considered hurtful to almost anyone alive. As a Jewish person I come across at least 3-4 times a day with the all-known Grammar Nazi that you all know, but as a person that lost a huge part of his family in the holocaust, am I offended by this WIDELY used meme? or by wide usage of the “Nazi” phrase everywhere in the open-source community? or maybe I should go up to all of the people that use MongoDB and ask them if they know how hurtful the word “Mongo” (Check the other uses section where it says “A variant of mong, a derogatory shortening of Mongoloid”) means to some people?

No. I am not offended either by the Nazi, and not even by 10gen (Guys, I love you).

I am not offended because people make this things either by mistake, either by purpose and in most of the time no matter what you do - someone can take offense. Being judgmental and complaining about hurtful things you find on the Internet is like complaining on the noise level in a Megadeath concert - it is there, and it will always be there.

So please, if you see someone making a mistake - or something that you think worths the heads-up - there is no need to start a witch hunt, let them know and I am sure that if they are reasonable people they will change whatever it is that is bothering you and beg for forgiveness.

Yours, Elad

Restraping Enum to Your Ruby Toolbelt

Where did my Enum go?

Enum is probably one of the things I miss most in Ruby. Not sure why - but as a fairly common design pattern I expected to see it more than I do in Ruby’s Stdlib (or maybe even Core) and in Ruby / Rails implementations around.

Enum (or Factor if you will) is basically a set of values called members (or elements) that act as a constant and represent some sort of a numeric (mostly integer) value. It is mainly used to represent a string constant in a numeric way, allowing easier serialization of data representation and avoiding recurring typs of long / annoying strings.

Java, C#, and even our beloved neighbor Python - all provide some kind of an implementation to Enum as part of their toolbelt, some databases like (MySQL)[http://dev.mysql.com/doc/refman/5.0/en/enum.html], Postgres provide a specific implementation “by the book” for enum types but some others like SQL-Server (yes, Microsoft again) provide some black magic to achieve an Enum representation:

An SQL-Server spell to create an enum type column
1
mycol VARCHAR(10) NOT NULL CHECK (mycol IN('Oranges', 'Apples', 'Pineapples'))

But, a decent Enum is still missing in Ruby.

Quick draw Enum in Ruby

If you ignore all the fancy words around the Enum definition, you are probably saying to yourself - “Eh, it’s a hash”.

Right.

The most simple way is to create a frozen hash constant that will hold all your constants:

Quick draw simple hash enum in ruby
1
2
3
4
5
6
7
8
class Canvas
  COLORS = {
              0 => :black,
              1 => :white,
              2 => :green,
              ...
            }.freeze
end

testing it out:

Using the quick draw hash enum
1
2
$> Canvas::COLORS[0]
:black

This implementation is rather simple and convenient - but not too easy to maintain and carries absolutely no syntactic sugar.

Note that if you want to access the numeric value via a given constant (ex: Canvas::Colors[:black]) you’ll need to implement external access methods for the frozen hash. Another problem I have with this implementation is that it is too specific, if you want an other class to use the COLORS “enum”, you’ll need to redefine it again.

Reusable Module Enum

The Reusable module implementation is very similar to the implementation that you’ll find in C#, Python and Java - a free module that allows the enum to be re-used in multiple classes and is basically all about defining constants:

Reusable Module Enum in Ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
module ColorsEnum
  BLACK = 0
  WHITE = 1
  GREEN = 2
end

class Canvas
  include ColorsEnum
end

class Wall
  include ColorsEnum
end

This form allows code re-using of course, but still lacks the ability to access the enum members by both numeric index and the constant.

Enum by method

Before reaching out to solve the dual access problem (isn’t it annoying to declare constants manually?) lets add some syntactic sugar to the constant definition process.

Generate an enum by method
1
2
3
4
5
6
7
8
9
10
11
12
13
class Object
  def self.enumify(*args)
    args.flatten.each_with_index do | const, i |
      const_set(const, i)
    end
  end
end

class Bowl
  enumify "ORANGES", "APPLES", "PINEAPPLES"
end

p Bowl::ORANGES # => 0

Now we are getting closer. We can’t use this syntactic sugar anywhere in our app to define enums like the big boys do, but it still doesn’t solve our dual access problem.

Enum with dual-access

The feature that almost all the Enum implementations I presented above are missing is the ability to access an enum member by either its value or by name. The following implementation (original from here) suggests a more robust module based implementation, it adds an object implementation for each enum member to store all member attributes (index for example) and extends the enum base class with the Enumerable module capabilities.

I used this base class and added some more attributes to the Enum::Member class to also store the actual value and allow dual access to both the key and the value of the member:

Enum with dual access
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class Enum < Module
  class Member < Module
    attr_reader :enum, :index, :syme

    def initialize(enum, index, syme)
      @enum, @index, @syme = enum, index, syme
      # Allow Color::Red.is_a?(Color) 
      extend enum
    end

    # Allow use of enum members as array indices 
    alias :to_int :index
    alias :to_i :index

    alias :to_sym :syme
    alias :to_s :name

    def name
      self.syme.to_s
    end

    # Allow comparison by index 
    def <=>(other)
      @index <=> other.index if other.respond_to?(:index)
    end

    include Comparable
  end

  def initialize(*symbols, &block)
    @members = []
    symbols.each_with_index do |symbol, index|
      # Allow Enum.new(:foo)
      symbol = symbol.to_s.sub(/^[a-z]/){|letter| letter.upcase}.to_sym
      member = Enum::Member.new(self, index, symbol)
      const_set(symbol, member)
      @members << member
    end
    super(&block)
  end

  def all
    all = {}
    @members.each_with_index do |member, index|
      all[index] = member
    end
  end

  def [](val)
    if val.is_a?(Numeric)
      @members[val]
    elsif val.is_a?(Symbol)
      @members.select {|member| member.syme == val }.first
    elsif val.is_a?(String)
      @members.select {|member| member.name == val }.first
    end
  end

  def size
    @members.size
  end

  alias :length :size

  def first(*args)
    @members.first(*args)
  end

  def last(*args)
    @members.last(*args)
  end

  def each(&block)
    @members.each(&block)
  end

  include Enumerable
end

Lets focus on the Enum#[] method in line 49:

Enum#[]
1
2
3
4
5
6
7
8
9
def [](val)
  if val.is_a?(Numeric)
    @members[val]
  elsif val.is_a?(Symbol)
    @members.select {|member| member.syme == val }.first
  elsif val.is_a?(String)
    @members.select {|member| member.name == val }.first
  end
end

This method allows the dual-access mode I discussed before when doing the following

  • When getting a Numeric value as a parameter it checks it against any memeber’s #index attribute
  • When getting a string it compares it to the #name attribute.

Voila!

This implementation stores the member list in an array member named @members and delegates manually all the Array and Enumerable methods to this array member. Seems like we can simply inherit from Array and drop all these delegation methods.

Ruby Set based Enum

Set implements a collection of unordered values with no duplicates. By using Set as a parent we inherit its ability to traverse members, we don’t need to implement and manage delegation to an array member and we don’t need to create constants (I’ll discuss that later in this article):

Set based ruby Enum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
require 'set'

class Enum < Set

  class Member

    include Comparable
    attr_reader :symbol
    attr_reader :index
    attr_reader :name

    def initialize(value, index = 0, name = nil)
      @symbol = value.to_sym
      @index = index.to_i
      @name = name ||= value
    end

    def <=>(other_member)
      self.symbol <=> other_member.symbol
    end
  end

  def initialize(*members)
    super()
    populate(members)
  end

  def to_a
    super.sort_by(&:index)
  end

  def each
    block_given? or return enum_for(__method__)
    self.to_a.each { |o| yield(o) }
    self
  end

  def [](index_or_symbol)
    if index_or_symbol.is_a?(Symbol)
      return self.select {|member| member.symbol == index_or_symbol }.first
    elsif index_or_symbol.is_a?(Integer)
      return self.select {|member| member.index == index_or_symbol }.first
    end
  end

  protected

  def populate(members)
    members.each_with_index do |member, index|
      self.add(Enum::Member.new(member, index)) unless self.to_a.collect(&:name).include?(member)
    end
  end
end

First, I’ll focus on the #populate method. This method is fired when #initialize finishes and appends all members applied to the Enum set. Line 50 is where all the magic happens - it creates a new Enum::Member and adds it to the set, unless it already exists.

Wait! Aren’t set members already unique by default?

Yes, they are. But this implementation runs into a Ruby brick wall. The ruby Set keeps an internal hash (named @hash surprisingly) that holds the member as keys and sets a value of true for each one when they are entered. Further more, Set#include? is delegated to Hash that on its turn - runs a native C code that compares objects directly.

In our case it will result in something like this:

Hash#include?
1
Enum::Member.new.object_id == Enum::Member.new.object_id

Which, no matter if both members have the same attributes, will return false.

Set#include? does not exercise the Comparable module convenience I included in Enum::Member, so we need to do a comparison on our own.

And why didn’t you use Constants?

It is easy and smart to use constants when you can take care of any naming conventions and constant name limitations that Ruby introduces, in our case we allow Enum::Member to initialize with any kind of string, even ones that don’t pass the constant name restrictions, some examples are:

Constant naming limitations
1
2
3
4
5
6
7
8
Enum::Member.new("888betonline", 0).symbol #=> :"888betonline"

# Same in a constant
Object.const_set(888BETONLINE, 0)
SyntaxError: compile error
(irb):10: syntax error, unexpected tCONSTANT, expecting ')'
User.const_set(888BETONLINE, 0)
                           ^

Since we don’t know or even want to restrict our enum value names, dropping the constant convention out of the loop seemed like the right thing to do.

Update: A clean, simple and perfect Hash

After this post was published, a talked to my friend Daniel about the Set implementation. He suggested the the Set usage is not required since that #include? bug causes me to write the presence test myself and that anyway, I traverse the members myself so the Set has no meaning.

he later came up with this suggestion:

Simple hash enum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Enum < Hash
  def initialize(*members)
    super()
    @rev = {}
    members.each_with_index {|m,i| self[i] = m }
  end
  def [](k)
     super || @rev[k]
  end
  def []=(k,v)
    @rev[v] = k
    super
  end
end

enum  = Enum.new("Apples", "Oranges")

enum[:Apples] # => 0
enum[0]       # => :Apples 

This solution, not only answer the dual access requirement - but it drops the need to use an internal Enum::Member inclusion. Definitely a winner

Conclusion

Ruby misses a real enum implementation. I would be happy to see an official one come out in one of the next releases. Until then the Hash implementation is something I will be using.

Source available here, fork away.

Bag O’ Links - 26/2/2011

Yeah, since i’ve been working for fiverr.com it’s been really hard to find the time and compile a decent bag’o’links.. hopefully i’ll get back to that soon along with posting some cool Rails experiences from Fiverr.

Well, back to business:

Links

Treasures

  • Rack-modpagespeed – a rack app that does all kinds of cool things to make your pages load faster.
  • Terminator – ninja command line.
  • Rails cells – not really sure what it’s actually good for.

Convention Over Manipulation

In the past 5 years or so I came across countless Rails applications, some were written by several of the best coders i know around (Ryan Bigg and rBoard, Eric Davis and Redmine.. the list obviously carries on) and some were written by less “experienced” developers. Some write awesome codes and have great insights on almost everything you ask them, while others just try to “get things done” and not necessarily find the right way out.

People love Rails. Every person i forced into using it (@kensodev – you for example) almost immediately fell in love with it and started calling out those famous “i can’t believe it does that” statements rails noobs so often yell in excitement.

From that point on I see people going into 2 different directions:

  • Those that learn how to use Ruby and Rails’s strengths when needed, and when not to.
  • Those that will bend, twist, fold and squeeze Ruby and Rails into something it is not.

Those who turn to the second path aren’t stupid, bad developers or people that enjoy software sodomy (maybe), they are just people that haven’t invested enough time and effort in finding the right solution for their problem – an act that will probably end like the famous Twitter “Rails can’t scale” saga.

By manipulations i mean…

Twitter did something like that, although i am not in the heart of things i do remember reading some of the discussions made by Obie Fernandez and Alex from Twitter and it seems like they were using Rails wrong, and where it shouldn’t have been.
Keeping aside the fact that Rails and Ruby (just like any other language and framework) aren’t a magical solution to every single software pickle around, when you do decide to use a tool you better do it right.
Twitter overused a method named #kind_of? that identifies an object’s class (according to Obie’s response about scala at twitter) as a result of an architecture failure or just plain “if it works don’t touch it” mantra, and probably there was a better solution even before Rails was switched out.

Many developers abuse their tools, Rails developers aren’t unique. iv’e seen .Net pages that held a VIEWSTATE across the entire page but with Ruby and Rails i think it’s easier to skip that line between “Being creative” and “Being a smartass” which may lead to undesired side-affects on your application.

Another good example of a pointless manipulation is here on The Israeli Ruby on Rails group – session variable and model code discussion.
Long story short, Michael wanted a way to pass a session variable into a model. why you ask? because he needed that value to be rendered as part of to_xml.

Argh.

This is a perfect example of someone that bends conventions (MVC in this case) just to write “less code”. Obviously, the right answer to his question is “RTFM dude, use builder” and a happy little something.erb.xml view (which would have also given them the benefits of ActiveSupport and friends). further more the boys at Michal’s did this WTF plugin to make it easier for them to manipulate rails next time. sigh.

It’s easy to manipulate a framework like Rails. Ruby is durable, dynamic and fun – you don’t really want to use anything else when you are already using it. But sometimes like Michael showed – it’s easy to misuse those wonderful tools.
The thing that you as a developer should keep in mind is that you can probably solve every problem you have without bending things too much. yes, we all bend and manipulate Rails code in one way or another but the thing we need to keep in mind is to stay focus on the primary goal: finding the best solution, not using the first one we think is working.
Rails always supplies you with a tool to perform a general task (to_xml for example) and a way to customize it on your own (xml views) – personally i always check if the tool/method/object i think of using is the simple or the customizable one and if i really need more than the simple need in a task.

i wouldn’t use #to_xml on an instance if i had to include/exclude too many fields from it or it’s associations, i’d use builder. but if all i need is the basic object in xml format, there is no reason i should re-build the entire thing.

Conclusion

Put an effort in finding the right solution for your problem. don’t think that because rails is easy and simple you can make do what ever you want and it won’t cry :)
There are people always willing to help on IRC (#rubyonrails, and #railsbridge on irc.freenode.new) and on twitter if you just drop by and ask.. it’s easier to learn that way.

Bag O’ Links - 9/11/2010

Links

Treasures

  • HTML5 Boilerplate – TML5 Boilerplate is the professional badass’s base HTML/CSS/JS template for a fast, robust and future-proof site. really awesome.
  • Developing your Resume – your resume, on Github.
  • Google API console – test drive your Google API usage.
  • Hola – async’ed JS chat application.
  • .gitignore template for Rails – looks good, only `database.yml` is missing (i copy it from a server-resident shared folder after capistrano’s code-update).
  • RubyRacer – Run V8 JS interpreter through Ruby.
  • Ruby XMPP bot – running on GMail’s chat, nice (reminds me of Barking Iguana’s XMPP4R-simple makes XMPP simple test).
  • ZeroMQ – another message queuing engine.
  • The Devchix wiki – really good stuff here, i actually converted their installation process into a muppet/babushka recipe for new server installations.

Bag O’ Links - 3/11/2010

Links

Treasures

  • Shapado – Rails + MongoDB based stackoverflow clone.
  • SproutsProject – Sprouts is an open-source, cross-platform project generation and configuration tool for ActionScript 2, ActionScript 3, Adobe AIR and Flex projects.
  • Whereuat – Adds a slide out panel to your rails app that directs clients to test stories that have been marked as ‘delivered’ in Pivotal Tracker. brilliant.
  • RubyRegex – Ruby regular expressions library.
  • OpenStack – open source cloud control and management tools.
  • Jo – Awesome JS UI framework.
  • SocialStream – a Devise dependent social features plugin for rails.
  • ruote – a workflow engine, not a state machine.

Bag O’ Links - 24/10/2010 (Back!)

Yeah, i know i said bag’o’links will go out of service a few months ago and that i’m going to move it the Nautilus6 website, but overall there were few other things i had to do with Nautilus6 prior to that.. i’ll get to it when i can but it doesn’t mean i can’t re-post links does it?

Links and fun

Favorite RailsRumble Apps

Last weekend this year’s “RailsRumble” took place, of course i missed it but i did had a chance to peek in and choose some favs:

  • RailsWizard – generate your own Rails template by a simple click/choose interface. i like it so far and anxious to see how far it goes.
  • Caviar – charge your clients by results.
  • Empower – build a development environment around your app, nice.
  • FontStacks – generate CSS that contains awesome fonts (font-face).
  • GitWrite – blogging for nerds, looks like a web supported Jekyll.. nice, i like it and waiting for some improvements and additions.

Treasures

Last sad note

About 10 days ago we lost a friend. Fares Yussuf Donaldson (a.k.a invalidrecord on IRC) died.
We will miss you buddy.

No More Bag of Links

For the past 18~ months or so i’ve been trying to keep a reasonable posting rate of my “Bag o Links” collection. Recently it has become too hard to spare the time needed to bounce my favorite links up, especially due to the fact we are investing most of our ‘extra’ time in Nautilus6 to sketching out a new company website.

Bag o links will be back on the new company site pretty soon i think, but for now it’s on hold.

Bag O’ Links - 24/5/2010

Phew! it was a long time since i last posted Bago’. Israel keeps me busy.

Treasures

  • jsChat – a nice chat engine using javascript and MongoDB.
  • Google Fonts API – nice, font-face will get a boost from this one. (here are the fonts)
  • fancy-buttons – Easily style buttons with beautiful CSS3 features like gradients, rounded corners, etc. Don’t worry the buttons also degrade nicely for browsers with no support. requires Compass though, which is annoying.
  • ZeroMQ – java based MQ manager. looks great.
  • ShowOff – presentations made simple. wicked.
  • Google’s S3? – Storage for developers.
  • to_xls – convert objects to excel spreadsheets.
  • KingSOA – KingSoa orchestrates a SOA landscape, by knowing where services live and how to call them.
  • Linkscape – a library to access SEOmoz’s API.
  • ActiveCart – a basic shopping cart implementation.
  • MongoHub – native MacOS MongoDB GUI.

Bag O’ Links - 4/5/2010

Links

Treasures