Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to use an integer as method name in Ruby?

Tags:

ruby

Here's an example of what I'm trying to do:

def 9()
  run_playback_command(NINE_COMMAND)
end

I'd like it that way because it's supposed to be used later like this:

if(channelNumber != nil)
  splitChannel = "#{channelNumber}".split(//)
  if(splitChannel[3] != nil)
    response = "#{splitChannel[3]}"()
  end
  if(splitChannel[2] != nil)
    response = "#{splitChannel[2]}"()
  end
  if(splitChannel[1] != nil)
    response = "#{splitChannel[1]}"()
  end
  if(splitChannel[0] != nil)
    response = "#{splitChannel[0]}"()
  end
end

Sorry for the trouble if this is a simple question! I'm very new at Ruby.

Edit:

Here's what I'm trying to get Siri to do:

if(phrase.match(/(switch to |go to )channel (.+)\s (on )?(the )?(directv|direct tv)( dvr| receiver)?/i))

  self.plugin_manager.block_rest_of_session_from_server
  response = nil

  if(phrase.match(/channel \s([0-9]+|zero|one|two|three|four|five|six|seven|eight|nine)/))        
    channelNumber = $1

    if(channelNumber.to_i == 0)
      channelNumber = map_siri_numbers_to_int(channelNumber)
    end

    channelNumber.to_s.each_char{ |c| run_playback_command(COMMAND[c]) }
  end

No wonder it's not reading the channel. Help?

like image 941
williammck Avatar asked Dec 21 '22 05:12

williammck


2 Answers

Is this what you need?

COMMAND = {
  "0" => ZERO_COMMAND,
  "1" => ONE_COMMAND,
  "2" => TWO_COMMAND,
  #...
  "9" => NINE_COMMAND
}

channelNumber.to_s.each_char{ |c| run_playback_command(COMMAND[c]) }

You don't even need to check for nil? since nil.to_s is an empty string, and thus the each_char iterator will not process any characters.

As an aside, you cannot define (or invoke) a method whose name is not a legal identifier (you can't start with a digit) using standard syntax, but this is technically possible:

class Foo
  define_method "9" do
    puts "It's nine!"
  end
end

f = Foo.new
c = "9"
f.send(c)
#=> "It's nine!"

p (f.methods - Object.methods)
#=> [:"9"]
like image 130
Phrogz Avatar answered Jan 23 '23 22:01

Phrogz


here, have a proper solution:

callbacks = {"9" => lambda { run_playback_command(NINE_COMMAND) } }

if channelNumber
  splitChannel = channelNumber.to_s.split(//)
  splitChannel.each do |number|
    callbacks[number].call
  end
end

Your collection of ifs is just a very verbose way of writing splitChannel.each.

like image 32
Dominik Honnef Avatar answered Jan 23 '23 21:01

Dominik Honnef