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
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.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 be1
again, hence the infinite loop. (Hope you get the idea)pop
wouldn't work on string, just because we can access characters using indexes like for arrays, we can't usepop
for strings.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
Duplicate Elements of Array in Ruby
Definition of Method in Top Level
Print Unicode Escape Codes from Variable
Rails Form_For Never Invokes the Create Controller Action to Use Redirect_To
Instantiate Capybara Browser and Set a Proxy
Calling Protected Class Method from Instance Method in Ruby
Placing Sub Arrays in Neat Rows
Login Session Data Not Persisting in Rails 6
Recurring Billing with Rails and Activemerchant: Best Practices, Pitfalls, Gotchas
Intermingling Attr_Accessor and an Initialize Method in One Class
Rails 4 Order by Virtual Attribute
Invalid Source Reflection MACro :Has_Many :Through
Ruby Check Whether Program Is Currently Being Closed
Sum of All Amount If Charge Dates Are the Same in Stripe
Rails How to Use Associated Model with the Admin Namespace
Ruby String Prepend '\' Character
How to Keep Sending Emails to Users Every Week Depending on User Date Input in Rails