Ruby Gets() Not Returning Correct String

Ruby gets() not returning correct string

I think the gets includes the newline at the end of the input. try using gets.chomp instead

irb(main):001:0> input = $stdin.gets
hello
=> "hello\n"
irb(main):002:0> input = $stdin.gets.chomp
hello
=> "hello"

Replacing the to_s method in Ruby. Not printing out desired string

When given arguments that are not strings or arrays puts calls rb_obj_as_string to turn its arguments into strings (see rb_io_puts)

If you search for rb_obj_as_string through the ruby codebase (I find http://rxr.whitequark.org useful for this) you can see it's defined as

VALUE rb_obj_as_string(VALUE obj)
{
VALUE str;

if (RB_TYPE_P(obj, T_STRING)) {
return obj;
}
str = rb_funcall(obj, id_to_s, 0);
if (!RB_TYPE_P(str, T_STRING))
return rb_any_to_s(obj);
if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
return str;
}

In brief this:

  • returns straightaway if the argument is already a string
  • calls to_s
  • if the result is not a string, call rb_any_to_s and return that.

rb_any_to_s is what implements the default "class name and id" result that you're seeing: for any object it returns a string of the form #<ClassName: 0x1234567890abcdef>

Returning to your code, when you run puts player1 it calls rb_obj_as_string to convert your player to a string.

This first calls your to_s method, which uses puts to output your message. Your method then returns nil (because that's what puts always returns) so ruby calls rb_any_to_s, and that is what the outermost puts ends up using.

why does this ruby code not return anything?

There were a lot of logical issues in your code.
here's something that might just work for you

def dasherize_number(num)
string = num.to_s
str_len = string.length

i = 0

while i < str_len
next if string[i] == '-'
if (string[i].to_i % 2) != 0
string[i] = '-' + string[i] + '-'
str_len = string.length
i += 3
else
i += 1
end
end

if string[0] == '-'
string = string[1..-1]
end

if (string[string.length - 1]) == '-'
string = string[0..-2]
end

string.gsub('--', '-')
end

Explaination

  1. Firstly, you had this condition in your while loop i < string.length
    Which wouldn't work, because the length of the string keeps changing. So i've used a variable to store the value and update the variable if the string is updated.

  2. If the string is updated, we can be sure that we can skip the next two indexes.
    eg: number inputed -> 122
    then after first iteration the string would be -1-22
    so we don't want to run the same condition for the next index because, that would be 1 again, hence the infinite loop. (Hope you get the idea)

  3. pop wouldn't work on string, just because we can access characters using indexes like for arrays, we can't use pop for strings.

  4. To make sure there are no consecutive dashes, i've used gsub to replace them with single dash.

Ruby: 'gets' method called inside a method saves Nil instead of Input

You are using downcase! instead of downcase. downcase! changes a string in-place and returns nil if there were no changes (which is what is happening here).

str = "teSt"
puts str.downcase # test
puts str # teSt
str.downcase!
puts str # test

See the documentation for downcase!

Ruby gets/puts only for strings?

If you are using to_i, then chomp before that is redundant. So you can do:

puts 'Hello there, Can you tell me your favourite number?'
num = gets.to_i
puts 'Your favourite number is ' + num.to_s + '?'
puts 'Well its not bad but ' + (num * 10).to_s + ' is literally 10 times better!'

But generally, using "#{}" is better since you do not have to care about to_s, and it runs faster, and is easier to see. The method String#+ is particularly very slow.

puts 'Hello there, Can you tell me your favourite number?'
num = gets.to_i
puts "Your favourite number is #{num}?"
puts "Well its not bad but #{num * 10} is literally 10 times better!"

Ruby: String Comparison Issues

gets returns the entire string entered, including the newline, so when they type "M" and press enter the string you get back is "M\n". To get rid of the trailing newline, use String#chomp, i.e replace your first line with answer = gets.chomp.

new to Ruby, if else statement not working

if i put in 100, shouldn't it print "go to server room"?

I assume that you want your program to read user input and then print different messages depending on that input.

[I'm] new to Ruby

Okay, so first of all, Ruby doesn't do implicit type conversion like JavaScript or PHP. Or not to the same extent. It does allow you to compare floats and integers:

1.0 == 1 #=> true

but comparing strings and integers doesn't work that way:

'1' == 1 #=> false

You have to convert it yourself:

'1'.to_i == 1 #=> true

Since your input is supposed to be an integer, we can convert it right away:

stress = gets.to_i

When entering 100enter, gets will return "100\n" and to_i will interpret that as an integer, returning 100 (to_i ignores the trailing newline, so we don't need chomp).

stress is now an integer, so you can compare it to other integers:

if stress == 100
puts "Go to server room"
elsif stress > 50
puts "Take a break"
else
puts "Continue working"
end

I've changed === to ==. For comparisons you almost always want the latter. === has special meaning in Ruby. Just avoid it for now.

The above code would already work, but you wanted a method. You could call your method stress, i.e. use the same name for the variable and the method. But it makes your code much harder to understand. So let's choose a different method name, e.g. message. While we're at it, let's also remove the repeated puts calls, so it just returns the message without printing it:

def message(stress)
if stress == 100
"Go to server room"
elsif stress > 50
"Take a break"
else
"Continue working"
end
end

You can call the above method via:

input = gets.to_i
puts message(input) # <- 'puts' is now here

I've deliberately chosen a different variable name for the input to distinguish it from the method argument.

Defining Liquid tag, returning string works but processing to return string doesn't?

I've spotted the problem :

if (person.index.to_s() == @text.to_s())
return person.display
end

Here your code tries to use index method on person. person.['index'].to_s() is better. Same for person.display => person['display']

Once here you still have a problem with person.index.to_s() == @text.to_s(). As your liquid tag is {% Person_Index 2 %}, @text is "2 " with a space.
So "2" != "2 ". We need to strip strings :

if (person['index'].to_s().strip == @text.to_s().strip)

is good but I prefer

if (person['index'].to_i() == @text.to_i())
return person['display']
end


Related Topics



Leave a reply



Submit