Ruby “gotchas” – ‘and’ and &&

Have you ever wondered what the difference between ‘and’ and && operators is in Ruby? Check the example below.

module RubyExercise1
  class UsersList
    attr_reader :users
    NoUserError = Class.new(StandardError)

    def initialize
      @users = []
    end

    def create_new_user(name)
      user = Struct.new(:user_name).new(name)
      add_user_to_list(user)
      user_name = get_user_name(user)
      "Created user with name: #{user_name}"
    end


    def get_user_name(user)
      user_name = user and user.user_name
      if user_name.nil? || user_name.strip.empty?
        raise NoUserError, "No user or empty name"
      else
        user_name
      end
    end


    private


    def add_user_to_list(user)
      @users << user
    end

  end

end

puts RubyExercise1::UsersList.new.create_new_user("Jedrek")
>> NoMethodError: undefined method `strip' for #<struct user_name="Jedrek">

If you look at the line

user_name = user and user.user_name

you might think that the user_name should be a String, but the error message clearly says that it is not a String, it’s the Struct object. So how is this? Well, it turns out that ‘and’ and ‘&&’ have lower precedence than =:

> a = true && false
 => false 
> a
 => false 
> a = true and false
 => false 
> a
 => true

So this explains why you should always avoid ‘and’!
“The and and or keywords are banned. The minimal added readability is just not worth the high probability of introducing subtle bugs. For boolean expressions, always use && and || instead. For flow control, use if and unless; && and || are also acceptable but less clear.”(The Ruby Style Guide)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s