I just started learning how to code and I tried running some basic instructions.
To start, I have the following:
print 'hello'
v= "yes"
["test","words","okay"].
each do |v|
puts "This is the test word #{v}"
end
which gives me the following out put
irb(main):053:0> print 'hello'
hello=> nil
irb(main):054:0> v= "yes"
=> "yes"
irb(main):055:0> ["test","words","okay"].
irb(main):056:0* each do |v|
irb(main):057:1* puts "This is the test word #{v}"
irb(main):058:1> end
This is the test word test
This is the test word words
This is the test word okay
=> ["test", "words", "okay"]
Why exactly is the => symbol appearing at the end of my code which references back to my array of strings? From what I understand so far, I know that => can be used to assign Strings to symbols in hashes (I think), but what other purpose does the symbol serve and why is it in my code?
The => you are seeing is an indicator of the return value of whatever command you run using irb.
So for instance the command print 'hello' results in hello=> nil because the string 'hello' is output to the console (with no new line), and the return value of the print method is nil.
When you invoke the each method on an array, after your output text is printed you see => ["test", "words", "okay"] because that is the return value of the each method (this can be convenient because it allows for chaining methods together).
As an experiment, try running different commands to see what their return values are. What is the return value of an assignment? (E.G. a = 3). Can you think of any useful ways to use return values?
Related
I doing a Ruby botcamp. I'm supposed to write code that replaces all user input of 's' with 'th' so it reads like Daffy Duck is speaking. If I enter an s it will be replaced with th. That works! But If I don't enter an 's' it's supposed to print that none were included in my elsif statemnt. Instead I'm getting the error 'undefined method `include?' for nil:NilClass'. Other than that error, the interpretor is telling me the code is good.
print "Input a string: "
user_input=gets.chomp.downcase!
if user_input.include?"s"
user_input.gsub!(/s/, "th")
puts "Your string is #{user_input}!"
elsif
puts "There are no s's in your string!"
end
Any ideas on what I need to change?
You need to be careful with built-in ruby methods that end with an exclamation point (!). A lot of them will return nil if no changes were made:
'test'.downcase! # => nil
'Test'.downcase! # => "test"
Since you are assigning the result to a variable, there's no need to use the exclamation point method, since those modify in-place, you can just use the normal downcase method.
'test'.downcase # => "test"
You also later on have an elsif with no condition, that should probably just be an else. It's actually executing the first line of the "body" of the elsif as the conditional:
if false
puts "a"
elsif
puts "b" # recall that `puts` returns `nil`
puts "c"
else
puts "d"
end
This results in
b
d
being output
I was testing the scan method to try and better understand it. I was using IRB in my command line to test it, using the example provided in the ruby documentation:
a = "cruel world"
a.scan(/(.)(.)/) {|x,y| print y, x }
Should return:
rceu lowlr
Well, when I ran it, it did return rceu lowlr=> "cruel world":
$ irb
irb(main):001:0> a = "cruel world"
=> "cruel world"
irb(main):002:0> a.scan(/(.)(.)/) {|x,y| print y, x }
rceu lowlr=> "cruel world"
irb(main):003:0>
Usually when use IRB, the left side of the => is blank, and the right side is the returned value. In this case, the left side is the returned value...and the right side is just...what the return value would be if it was spelled correctly? Why?
The => indicates the return value of whatever code you just ran. That is, if I set
b = a.scan(/(.)(.)/) {|x,y| print y, x }
then the value of b would be cruel world. The reason it doesn't appear on a new line is that print doesn't automatically add a new line at the end of whatever it prints to the screen. If you use puts instead of print you'll see that each character appears on its own line, and => "cruel world" appears at the bottom on its own line.
I am brand new to Ruby and am coming from a Python background. To help learn the language, I'm porting an existing Python script so I can do a side by side comparison. Thus far, I have a small bit of code and am confused as to why 'nil' prints to the console. Code below:
#!/usr/bin/ruby
require 'date'
backup_dirs = ['/backups/db', '/backups/log']
backup_dirs.each do |backup_dir|
Dir.glob(backup_dir + '/' + '*.*.*.*.*.*').each do |filename|
begin
creation_date = DateTime.strptime(filename.split('.')[3], '%m%d%Y%H%M')
rescue
puts "Skipping #{filename}, invalid file."
end
end
puts 'File is okay.'
end
If the DateTime.strptime method throws an exception, rescue runs and puts prints out the string fine. Except, after it comes a nil. I "googled" and found that puts returns nil. But why does that show only in the rescue area and not in the File is okay. line.
I.e. an example rescue output would be:
Skipping /backups/log/fs.server.dir.999999999999.14.log, invalid file.
nil
And, how do I make it stop displaying that to the console? I'm sure this is a fundamental language thing, just very new to the language so any insight would be much appreciated.
Thanks - Tom
All... sorry. I figured this out. In the actual code I was doing a puts creation_date and that is what was causing the nil to show... as it very well should!
First day learning the language, oops! Did learn a lot about puts though... appreciate all of the answers, sorry for wasting everyones' time.
This is expected behavior. Ruby methods will return the last statement evaluated if return whatever is not specified.
In the sample you have provided you are ending with a puts statement.
puts writes your output then returns nil and subsequently your method returns nil
From irb just run the following two statements to see this in action.
puts 'foo'
'foo'
This is actually because of the #puts method you're calling.
puts(obj, ...) → nil
Writes the given objects to ios as with IO#print. Writes a record separator (typically a
newline) after any that do not already end with a newline sequence. If
called with an array argument, writes each element on a new line. If
called without arguments, outputs a single record separator.
$stdout.puts("this", "is", "a", "test") produces:
this is a test
You can check that in pry/irb:
[9] pry(main)> puts "Hello"
Hello
=> nil
i am working though LearnTocodethehardway.com http://ruby.learncodethehardway.org/book/ex25.html
On ex25. In the example there is a module that has a bunch of methods that return or print values. The Print_last_word method when supplied with an array of strings just puts nil. it does this even in his example output. My question would then be why?
To be precise, it doesn't puts nil - it puts the last word and returns nil. Here's the example output:
>> Ex25.print_last_word(words)
wait. # <- this is the output
=> nil # <- this is the return value
puts always returns nil.
UPDATE
There seems to be a bug in print_first_word:
module Ex25
def Ex25.print_first_word(words)
word = words.pop(0)
puts word
end
end
Ex25.print_first_word(["foo", "bar", "baz"])
#=> nil
This is because ["foo", "bar", "baz"].pop(0) returns an empty array and puts [] just returns nil without printing anything.
A working implementation (in the exercise's style) could look like this:
module Ex25
def Ex25.print_first_word(words)
word = words.shift
puts word
end
end
To make it more easy to understand:
"puts" never is used for its return value. It is used for its side effect if you wanted a method that would return a word, you would then do something with that word.
words = ["apple", "cucumber", "apple"]
def give_me_first_word(array_of_words)
array_of_words.first
end
variable_to_be_used_later = give_me_first_word(words)
This function would return "apple"(and in this case the variable would be assigned "apple"), but it would puts nothing to the screen. This value would then be used in another program or function.
If you puts a value, you would then not need to return it to any other program as it's already served its purpose. It's actually intuitive because if puts also returned the value, it would be doing two things. The counterpart to "puts" would be "return" that simply returns the value and does not display it to the screen.
Look at this code :
def hello
p "Hey!"
end
p hello
the output will be:
"Hey!"
"Hey!"
=> "Hey!"
And so here is my conclusion: puts itself returns the text which is going to be sent in output in Ruby code, else it wouldn't print "Hey!" again. What is happening while printing the string? If puts doesn't send it to standard output directly, who is responsible for it and how?
All Methods Return a Value
In Ruby, almost everything returns a value, even if that value is nil. However, in your case the issue is that Kernel#p and Kernel#puts differ in the values they return.
def hello
# Print string literal, then return
# the printed object.
p "Hey!"
end
# Print the return value of main#hello.
p hello
As a result, the string gets printed once inside the method, and then the method's return value is passed to Kernel#p and printed again. This is by design.
Use Kernel#puts to Avoid Duplicated Output
def hello
# Print string; return nil.
puts "Hey!"
end
# Calls main#hello, but prints nil (blank line).
puts hello
This will result in the string literal being printed inside the method, and then a blank line printed since the return value from the method is nil.
Hey!
=> nil
The Right Way
If you want to avoid the blank line, avoid sending to standard output more than once. For example:
def hello
'Hey!'
end
p hello
If the p method returns the string it's given, then hello would return that as well, which means that the secondary p call would repeat it.
This is probably why puts returns nil by default.