What is the difference between print and puts? - ruby

For example in this line of code I wrote, print and puts produce different results.
1.upto(1000).each { |i| print i if i % 2 == 0 }

puts adds a new line to the end of each argument if there is not one already.
print does not add a new line.
For example:
puts [[1,2,3], [4,5,nil]] Would return:
1
2
3
4
5
Whereas print [[1,2,3], [4,5,nil]]
would return:
[[1,2,3], [4,5,nil]]
Notice how puts does not output the nil value whereas print does.

A big difference is if you are displaying arrays.
Especially ones with NIL.
For example:
print [nil, 1, 2]
gives
[nil, 1, 2]
but
puts [nil, 1, 2]
gives
1
2
Note, no appearing nil item (just a blank line) and each item on a different line.

print outputs each argument, followed by $,, to $stdout, followed by $\. It is equivalent to args.join($,) + $\
puts sets both $, and $\ to "\n" and then does the same thing as print. The key difference being that each argument is a new line with puts.
You can require 'english' to access those global variables with user-friendly names.

The API docs give some good hints:
print() → nil
print(obj, ...) → nil
Writes the given object(s) to ios. Returns nil.
The stream must be opened for writing. Each given object that isn't a
string will be converted by calling its to_s method. When
called without arguments, prints the contents of $_.
If the output field separator ($,) is not nil, it
is inserted between objects. If the output record separator
($\) is not nil, it is appended to the output.
...
puts(obj, ...) → nil
Writes the given object(s) to ios. Writes a newline after any that
do not already end with a newline sequence. Returns nil.
The stream must be opened for writing. If called with an array argument,
writes each element on a new line. Each given object that isn't a
string or array will be converted by calling its to_s method.
If called without arguments, outputs a single newline.
Experimenting a little with the points given above, the differences seem to be:
Called with multiple arguments, print separates them by the 'output field separator' $, (which defaults to nothing) while puts separates them by newlines. puts also puts a newline after the final argument, while print does not.
2.1.3 :001 > print 'hello', 'world'
helloworld => nil
2.1.3 :002 > puts 'hello', 'world'
hello
world
=> nil
2.1.3 :003 > $, = 'fanodd'
=> "fanodd"
2.1.3 :004 > print 'hello', 'world'
hellofanoddworld => nil
2.1.3 :005 > puts 'hello', 'world'
hello
world
=> nil
puts automatically unpacks arrays, while print does not:
2.1.3 :001 > print [1, [2, 3]], [4]
[1, [2, 3]][4] => nil
2.1.3 :002 > puts [1, [2, 3]], [4]
1
2
3
4
=> nil
print with no arguments prints $_ (the last thing read by gets), while puts prints a newline:
2.1.3 :001 > gets
hello world
=> "hello world\n"
2.1.3 :002 > puts
=> nil
2.1.3 :003 > print
hello world
=> nil
print writes the output record separator $\ after whatever it prints, while puts ignores this variable:
mark#lunchbox:~$ irb
2.1.3 :001 > $\ = 'MOOOOOOO!'
=> "MOOOOOOO!"
2.1.3 :002 > puts "Oink! Baa! Cluck! "
Oink! Baa! Cluck!
=> nil
2.1.3 :003 > print "Oink! Baa! Cluck! "
Oink! Baa! Cluck! MOOOOOOO! => nil

puts call the to_s of each argument and adds a new line to each string, if it does not end with new line.
print just output each argument by calling their to_s.
for example:
puts "one two":
one two
{new line}
puts "one two\n":
one two
{new line} #puts will not add a new line to the result, since the string ends with a new line
print "one two":
one two
print "one two\n":
one two
{new line}
And there is another way to output: p
For each object, directly writes obj.inspect followed by a newline to the program’s standard output.
It is helpful to output debugging message.
p "aa\n\t": aa\n\t

If you would like to output array within string using puts, you will get the same result as if you were using print:
puts "#{[0, 1, nil]}":
[0, 1, nil]
But if not withing a quoted string then yes. The only difference is between new line when we use puts.

Related

How to calculate elements of many arrays in Ruby?

I have a question about array in ruby
I have an array which contains many elements (strings with uppercases and down case ) and i want to know how many element (how many string) in this array contains an uppercase letters :
i obtain many element but i dont know how to calculate them
thank you.
array.each do |arr|
print arr.scan(/[A-Z]/)
end
Following your example, what you need is match? if you want a boolean result regarding if the element matches or not with an uppercase letter on it:
['foo', 'Foo', 'FoO'].each { |string| p string.match?(/[A-Z]/) }
# false
# true
# true
You can use count and pass a block to check if the current element returns true when evaluating if it contains uppercase characters. The result is the total of elements yielding a true value from the block:
['foo', 'Foo', 'FoO'].count { |string| /[[:upper:]]/ =~ string }
# 2
So i did:
a = ["HellO", "hello", "World", "worlD"]
b = 0
a.each do |x|
b += x.scan(/[A-Z]/).length
end
puts b # Which equals 4 in this case
The problem I had in some of the answers above with my array.
For Cary's answer I get 3 which somehow missing one of the capital letters.
For Sebastian's answer I get 3 as well which is also somehow missing one of the capital letters.
My array has 2 capitals in the first string, 1 in the third and 1 in the fourth.
Of course the more normal ruby way would be with b += x.scan(/[A-Z]/).count instead of .length but it worked for me in irb.
Some sample output from my console of the three methods:
030 > a.grep(/\p{Lu}/).size
=> 3
:031 > a.count {|string| /[[:upper:]]/ =~ string}
=> 3
:026 > a.each do |x|
:027 > b += x.scan(/[A-Z]/).length
:028?> end
=> ["HellO", "hello", "World", "worlD"]
:029 > b
=> 4
It appears as if the two regex examples above just check for any capital in the string and count it as one so if you had multiple in the same string like my first "HellO" then it only counts as one:
:039 > ["HellO"].grep(/\p{Lu}/).size
=> 1
:040 > ["HellO"].count {|string| /[[:upper:]]/ =~ string}
=> 1
Of course this may not matter to you but if the string is longer than one word it very well may:
2.5.3 :045 > a = ["Hello World"]
2.5.3 :047 > a.each do |x|
2.5.3 :048 > b += x.scan(/[A-Z]/).count
2.5.3 :049?> end
=> ["Hello World"]
2.5.3 :050 > b
=> 2
2.5.3 :051 > a.count {|string| /[[:upper:]]/ =~ string}
=> 1
2.5.3 :052 > a.grep(/\p{Lu}/).size
=> 1
With two words in one string it you can see the difference.
Of course I am counting the total capital letters when you asked,
i want to know how many element (how many string) in this array contains an uppercase letters
In which case either of the other two answers above do beautifully :)

In Ruby - How to get gsub!(bang) not return nil if it doesn't match and make it behave like .gsub

Lets say i want to remove leading space from a string
a = " Hello world"
puts a.gsub!(/^ /,"") # => "Hello World"
But if there is no leading space in the string
b = "Hello World"
puts a.gsub!(/^ /,"") # => nil
Now if I use just gsub instead of gsub it returns the string:
puts b.gsub(/^ /,"") # => "Hello World"
puts a.gsub(/^ /,"") # => "Hello World" (works for both a and b)
So is it possible to get gsub! to perform like gsub as shown above?
the reason is because gsub would create a new object everytime which I would like to avoid because I will be using at least 4 or 5 gsubs on the string I need to manipulate.
thanks
Here are two ways of doing that.
Add || a to the gsub expression
a.gsub!(/\A\s/,"") || a
would give you the desired result, namely removing the space, if present, and returning the string after any change is made. If no change is made, this reduces to nil || a #=> a. If a change is made the expression reduces to a.gsub!(/\A\s/,""). For example,
a = " Hello"
a.gsub!(/\A\s/,"") || a #=> "Hello"
a #=> "Hello"
a ="Hello"
a.gsub!(/\A\s/,"") || a #=> "Hello"
a #=> "Hello"
Although it makes no difference here, I prefer to use the beginning of string anchor, \A, rather than the beginning of line anchor, ^, I also prefer using a whitespace character \s to a space (assuming it couldn't be a tab) to a space, as an inadvertent extra space might not be noticed.
Use String#replace and the non-destructive method String#gsub
a = " Hello"
a.replace(a.gsub(/\A\s/,"")) #=> "Hello"
a #=> "Hello"
a ="Hello"
a.replace(a.gsub(/\A\s/,"")) #=> "Hello"
a #=> "Hello"
Answer:
b.gsub!(/(^ )?/,"") => "Hello World"
Explanation:
(...) Capture everything enclosed
a? Zero or one of a
— via http://rubular.com
Example:
irb(main):008:0> a = " Hello World"
=> " Hello World"
irb(main):009:0> b = "Hello World"
=> "Hello World"
irb(main):010:0> a.gsub!(/(^ )?/,"")
=> "Hello World"
irb(main):011:0> b.gsub!(/(^ )?/,"")
=> "Hello World"
Alternative:
b.gsub!(/^ |/,"") # => "Hello World" using "OR" pipe char
The code below adds a method to the String class that simply calls gsub! and then returns the String object that it was called on. So if the gsub! was "successful" and something has been subbed it returns the subbed string. Otherwise it will return the original string.
class String
def filled_gsub!(oldsubstr, newsubstr)
gsub!(oldsubstr, newsubstr)
self
end
end

How to write block in IRB?

For example, I want to implement this code in IRB, but it has single-line input so I can get how to write block there.
a = [3, 2, 1]
a[3] = a[2] - 1
a.each do |elt|
print elt+1
end
(Oh you mean IRB)
If you enter something that will be on multiple lines, ruby will wait until the final end is completed before running the code:
irb(main):001:0> def dostuff
irb(main):002:1> puts "things"
irb(main):003:1> end
=> :dostuff
irb(main):004:0> dostuff
things
=> nil
irb(main):005:0>
As you can see the number at the prompt changes depending on how deep the block-level is.

Separating a code chunk into the main parts and the expected return parts

What is the best way to separate a code chunk (string) into its "main parts" and its "expected return parts"? Here are my definitions:
An expected return part is a line that matches /^[ \t]*#[ \t]*=>/ followed by zero or more consecutive lines that do not match /^[ \t]*#[ \t]*=>/ but match /[ \t]*#(?!\{)/.
A main part is any consecutive lines that is not an expected return part.
Main parts and expected return parts may appear multiple times in a code chunk.
Given a string of code chunk, I want to get an array of arrays, each of which includes a flag of whether it is an expected return part, and the string. What is the best way to do this? For example, given a string code whose content is:
def foo bar
"hello" if bar
end
#=> foo(true) == "hello"
#=> foo(false) == nil
a = (0..3).to_a
#=> a == [
# 0,
# 1,
# 2,
# 3
# ]
I would like a return that would be equivalent to this:
[[false, <<CHUNK1], [true <<CHUNK2], [true, <<CHUNK3], [false, <<CHUNK4], [true, <<CHUNK5]]
def foo bar
"hello" if bar
end
CHUNK1
#=> foo(true) == "hello"
CHUNK2
#=> foo(false) == nil
CHUNK3
a = (0..3).to_a
CHUNK4
#=> a == [
# 0,
# 1,
# 2,
# 3
# ]
CHUNK5
This regex should match all expected returns:
^([ \t]*#[ \t]*=>.+(?:\n[ \t]*#(?![ \t]*=>).+)*)
Extract and then replace all expected returns from your string with a separator. Then split your string by the separator and you will have all main parts.
Test it here: http://rubular.com/r/ZYjqPQND28
There is a slight problem with your definition pertaining to the regex /[ \t]*#(?!>\{)/, by which I am assuming you meant /[ \t]*#(?!=>)/, because otherwise
#=> foo(true) == "hello"
#=> foo(false) == nil
would count as one chunk
Another approach would be to use this regex (completely unoptimised):
^([ \t]*#[ \t]*=>.+(?:\n[ \t]*#(?![ \t]*=>).+)*|(?:[ \t]*(?!#[ \t]*=>).+\n)*)
to simply split it into chunks correctly, then do a relatively simple regex test on each chunk to see if it is an expected return or main part.

Setting end-of-line character for puts

I have an array of entries I would like to print.
Being arr the array, I used just to write:
puts arr
Then I needed to use the DOS format end-of-line: \r\n, so I wrote:
arr.each { |e| print "#{e}\r\n" }
This works correctly, but I would like to know if there is a way to specify what end-of-line format to use so that I could write something like:
$eol = "\r\n"
puts arr
UPDATE 1
I know that puts will use the correct line-endings depending on the platform it is run on, but I need this because I will write the output to a file.
UPDATE 2
As Mark suggested, setting $\ is useful. Anyway it just works for print.
For example,
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> $\ = "\r\n"
=> "\r\n"
irb(main):003:0> print a
123
=> nil
irb(main):004:0> puts a
1
2
3
=> nil
print prints all array items on a single line and then add $\, while I would like the behaviour of puts: adding $\ after each item of the array.
Is this possible at all without using Array#each?
The Ruby variable $\ will set the record separator for calls to print and write:
>> $\ = '!!!'
=> "!!!"
>> print 'hi'
hi!!!=> nil
Alternatively you can refer to $\ as $OUTPUT_RECORD_SEPARATOR if you import the English module.
Kernel#puts is equivalent to STDOUT.puts; and IO.puts "writes a newline after every element that does not already end with a newline sequence". So you're out of luck with pure puts for arrays. However, the $, variable is the separator string output between parameters suck as Kernel#print and Array#join. So if you can handle calling print arr.join, this might be the best solution for what you're doing:
>> [1,2,3].join
=> "123"
>> $, = '---'
=> "---"
>> [1,2,3].join
=> "1---2---3"
>> $\ = '!!!'
=> "!!!"
>> print [1,2,3].join
1---2---3!!!=> nil

Resources