I have a ruby hash which looks like
{"10.1.1.6"=>"nick", "127.0.0.1"=>"nick1"}
But I can't manage to check if a certain string is already in the Hash. I tried has_value?, getting array of values using values then using include? to check if it contains it, but always returns false, when I know that it exists. For example, I try to add "172.16.10.252"=>"nick" to the hash and I do:
class SomeClass
def initialize(*args)
super(*args)
#nicks = Hash.new
end
def serve(io)
loop do
line = io.readline
ip = io.peeraddr[3]
begin
if /NICK (.*)/ =~ line
nick = $1
if #nicks.has_value?(nick) # it fails here
puts "New nick #{$1}"
#nicks[ip] = nick.gsub("\r", "")
io.puts "Your new nick is #{nick}"
else
message = {:ERROR => "100", :INFO=>"#{nick}"}.to_json
io.puts message
end
end
rescue Exception => e
puts "Exception! #{e}-#{e.backtrace}"
end
end
end
end
On irb it works fine, but on my script it doesn't
1.9.3p125 :001 > h = {"10.1.1.6"=>"nick", "127.0.0.1"=>"nick1"}
=> {"10.1.1.6"=>"nick", "127.0.0.1"=>"nick1"}
1.9.3p125 :002 > h.has_value?('nick')
=> true
1.9.3p125 :003 > if h.has_value?('nick')
1.9.3p125 :004?> puts "yes"
1.9.3p125 :005?> else
1.9.3p125 :006 > puts "no"
1.9.3p125 :007?> end
yes
=> nil
1.9.3p125 :008 >
What I'm doing wrong?
I'm not sure if you're using "$1" the way you intend to.
In your code at this line:
if /NICK (.*)/ =~ line
nick = $1
if #nicks.has_value?(nick) # it fails here
puts "New nick #{$1}"
if line is "NICK says a bunch of things", $1 will be "says a bunch of things". So you're not really looking for the value 'nick' in your hash, but for 'says a bunch of things'.
You should check how your regex is working, I wouldn't say anything is wrong with a hash.
Related
I thought that (in a while...do loop)
gets.chomp != ''
might match a carriage return from a terminal. It doesn't. What am I not understanding? Thank you.
String#chomp removes carriage returns from the string it is being called on.
If you remove chomp it should give you the expected output. See below:
2.1.2 :001 > def foo
2.1.2 :002?> while true do
2.1.2 :003 > puts gets != ''
2.1.2 :004?> end
2.1.2 :005?> end
=> :foo
2.1.2 :006 > foo
a
true
b
true
c
true
1
true
2
true
# about to press enter
true
true
Hope this helps
Is it possible to intercept IRB inputs? Specifically for class#Fixnum?
Example:
5
=> 5
What I need to do is: (pseudo code)
if IRB.input.is_a?(Fixnum)
some_method(IRB.input) # some_method(5)
end
Look at this file.
You can find Irb#eval_input method and patch them:
# code before
#scanner.set_input(#context.io) do
signal_status(:IN_INPUT) do
if l = #context.io.gets
if l.match(/^\d+$/)
puts 'Integer found!'
end
print l if #context.verbose?
else
if #context.ignore_eof? and #context.io.readable_after_eof?
l = "\n"
if #context.verbose?
printf "Use \"exit\" to leave %s\n", #context.ap_name
end
else
print "\n"
end
end
l
end
end
# code after
Irb output example:
spark#think:~$ irb
2.1.5 :001 > 123
Integer found!
=> 123
2.1.5 :002 > "string"
=> "string"
Below is the code which I tried in ruby console. Can anyone tell me why the output is different in this two cases for the same input.
2.1.4 :014 > def a_method
2.1.4 :015?> puts "enter"
2.1.4 :016?> a = gets.chomp
2.1.4 :018?> puts a
2.1.4 :019?> puts a.to_i
2.1.4 :020?> end
=> :a_method
2.1.4 :021 > a_method
enter
"12"
"12"
0 (output of a.to_i)
=> nil
2.1.4 :022 > "12".to_i
=> 12
Here I'm just converting a string number into integer by reading from console using gets, which is giving 0 as output. If I do the same by just giving "12".to_i then I'm getting proper output. Why is that?
Inspect the intermediate variable a when entering "12" (with quotes)
a = gets.chomp
# a => "\"12\""
a.to_i # => 0
"\"12\"".to_i # => 0
If you want to enter the actual number, not a string representation of it, do not use the quotes.
This output might help explain the issue:
2.1.1 :001 > def a_method
2.1.1 :002?> puts "enter"
2.1.1 :003?> a = gets.chomp
2.1.1 :004?> puts a.class.name
2.1.1 :005?> puts a
2.1.1 :006?> puts a.to_i
2.1.1 :007?> end
=> :a_method
2.1.1 :008 > a_method
enter
"12"
String
"12"
0
=> nil
2.1.1 :009 > a_method
enter
12
String
12
12
=> nil
gets is short for get string, so if you enter 12 it turns it into "12". As Jiří Pospíšil pointed out, if you enter "12", it turns it into "\"12\"", which to_i is unable to understand.
I'm following this tutorial to learn about creating shapes and colors on a canvas. Here is the issue I'm running into: When I try to run the command in the run_command method and I take the first letter of my command (command[0]), it is returning the number 98 to me. I am trying to match the first letter of the command to a letter of the alphabet, but am unable to do so. What's strange though, is that when I remove the first letter with "command.delete "b"", the letter is removed and I'm free to use the rest of the string as I please.
Here is my code:
require 'ruby-processing'
class ProcessArtist < Processing::App
def setup
background(0, 0, 0)
end
def draw
# Do Stuff
end
def key_pressed
if #queue.nil?
#queue = ""
end
if key != "\n"
#queue = #queue + key
else
warn "Time to run the command: #{#queue}"
run_command(#queue)
#queue = ""
end
end
def run_command(command)
puts "Running command: #{command}"
puts command[0]
if command[0] == "b"
command.delete "b"
command.split(",")
background(command[0].to_i,command[1].to_i,command[2].to_i)
else
puts command[0]
command.delete "b"
command.split(",")
background(command[0].to_i,command[1].to_i,command[2].to_i)
end
end
end
ProcessArtist.new(:width => 800, :height => 800,
:title => "ProcessArtist", :full_screen => false)
Ah, I see what I did wrong. It should have been:
def run_command(command)
puts "Running command: #{command}"
puts command[0]
if command[0] = "b"
command.delete "b"
command.split(",")
background(command[0].to_i,command[1].to_i,command[2].to_i)
else
puts command[0]
command.delete "b"
command.split(",")
background(command[0].to_i,command[1].to_i,command[2].to_i)
end
end
It seems like you're using ruby version older than 1.9.
In old version of ruby (1.8-), String#\[\] return Fixnum object representing ASCII value, not String object.
>> RUBY_VERSION
=> "1.8.7"
>> 'bcd'[0]
=> 98
To get string back, use one of followings:
>> 'bcd'[0,1]
=> "b"
>> 'bcd'[0..0]
=> "b"
>> 'bcd'[0].chr # this will not work in Ruby 1.9+, so not recommended.
=> "b"
For comparison:
>> 'bcd'[0] == 'b'
=> false
>> 'bcd'[0] == ?b
=> true
>> 'bcd'.start_with? 'b'
=> true
Two cases:
ruby-1.9.2-p180 > puts {}.class
=> NilClass
and
ruby-1.9.2-p180 > puts "a".class
String
=> nil
It looks like puts {}.class is equivalent to (puts {}).class and puts "a".class is equivalent to puts ("a".class). Why is it so?
It's treating {} as a block, not as a hash. RubyInside says so, and also shows how you can prove it using Ripper.