Animesh Pandey
Animesh Pandey

Reputation: 6018

How to create new functions for String class in Ruby?

I want to check the type of strings that I encounter:

class String
    def is_i?
        /\A[-+]?\d+\z/ === self
    end

    def is_path?
        pn = Pathname.new(self)
        pn.directory?
    end     
end

def check(key)
    puts case key
    when is_i?
        puts "Could be a number"
    when is_path?
        puts "This is a path"
    else
        puts "Ok"
    end
end

When I run check("1345425") I get the following error:

undefined method `is_i?' for main:Object (NoMethodError)

What should I do to correct it?

Upvotes: 2

Views: 173

Answers (3)

Thach Chau
Thach Chau

Reputation: 111

You may change it like this

class String
  def is_i?
    /\A[-+]?\d+\z/ === self
  end

  def is_path?
    pn = Pathname.new(self)
    pn.directory?
  end
end

def check(hash_key)
  puts case hash_key
  when Proc.new { hash_key.is_i? }
    return "Could be a number"
  when Proc.new { hash_key.is_path? }
    return "This is a path"
  else
    return "Ok"
  end
end

Running check('1312312') in irb returns result as "Could be a number"

Upvotes: 0

xea
xea

Reputation: 1214

Your check method isn't defined on the String class, so when you write when is_i? and when is_path? it is trying to call those methods on your main, hence the error.

You should call these methods on your String object (key) like this:

...
when key.is_i?
...
when key.is_path?
...

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

You have defined functions on String instance, hence:

def check(key)
    puts case
         when key.is_i?
           "Could be a number"
         when key.is_path?
           "This is a path"
         else
           "Ok"
         end
end

or

def check(key)
    puts case key
         when ->(s) { s.is_i? }
           "Could be a number"
         when ->(s) { s.is_path? }
           "This is a path"
         else
           "Ok"
         end
end

UPD Please also note that I removed superfluous subsequent calls to puts.

Upvotes: 2

Related Questions