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
Related
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 break the string into two lines in ruby code?
Is there specific symbol?
def my_def
path = "//div/p[contains(., 'This is a veeeeeeeryyyyyy looooonggggg string')]"
end
I wish to make something like that:
def my_def
path = "//div/p[contains(., 'This is a veeeeeeeryyyyyy
looooonggggg string')]"
end
Back slashes doesn't work right!
Ruby will automatically concatenate two strings that are adjacent:
foo = 'a' 'b'
foo # => "ab"
Normally a line-end signifies the end of the assignment:
foo = 'a'
'b'
foo # => "a"
so you can't simply break the lines and expect Ruby to figure out what to do.
\ marks the line as continuing, so you could use:
foo = "a" \
"b"
foo # => "ab"
Or, rely on the + String concatenation:
foo = 'a' +
'b'
foo # => "ab"
I'd probably use the + since it's most often used to join strings already, so its meaning is very obvious. Using \ leads to people joining really long expressions instead of breaking them down.
If your strings are really long, you can use some other tricks:
foo = [
'foo',
'bar'
].join
foo # => "foobar"
If you want to join the strings with a space, such as recombining sentences:
foo = [
'foo',
'bar'
].join(' ')
foo # => "foo bar"
or:
foo = [
'foo',
'bar'
] * ' '
foo # => "foo bar"
Building on all that, I'd use some combination of the above or simply something like:
long_str = 'This is a veeeeeeeryyyyyy' +
' looooonggggg string'
path = "//div/p[contains(., '#{ long_str }')]"
or:
long_str = [
'This is a veeeeeeeryyyyyy',
'looooonggggg string'
].join(' ')
path = "//div/p[contains(., '%s')]" % long_str
You can use a backward slash to indicate the string continues on the next line, like so:
str = "this is a long \
string"
print str # => this is a long string
If your string gets way too big, it might be a good idea to use here docs instead. They allow you to write pieces of text in the middle of the code:
str = <<HEREDOC
This is my string :)
Let's imbue code in the imbued doc: #{[4, 2, 3, 1].sort}
HEREDOC
print str
# => This is my string :)
# => Let's imbue code in the imbued doc: [1, 2, 3, 4]
HEREDOC can be any name you want to give it. You can learn more about here docs here.
I'd like to replace/duplicate a substring, between two delimeters -- e.g.,:
"This is (the string) I want to replace"
I'd like to strip out everything between the characters ( and ), and set that substr to a variable -- is there a built in function to do this?
I would just do:
my_string = "This is (the string) I want to replace"
p my_string.split(/[()]/) #=> ["This is ", "the string", " I want to replace"]
p my_string.split(/[()]/)[1] #=> "the string"
Here are two more ways to do it:
/\((?<inside_parenthesis>.*?)\)/ =~ my_string
p inside_parenthesis #=> "the string"
my_new_var = my_string[/\((.*?)\)/,1]
p my_new_var #=> "the string"
Edit - Examples to explain the last method:
my_string = 'hello there'
capture = /h(e)(ll)o/
p my_string[capture] #=> "hello"
p my_string[capture, 1] #=> "e"
p my_string[capture, 2] #=> "ll"
var = "This is (the string) I want to replace"[/(?<=\()[^)]*(?=\))/]
var # => "the string"
str = "This is (the string) I want to replace"
str.match(/\((.*)\)/)
some_var = $1 # => "the string"
As I understand, you want to remove or replace a substring as well as set a variable equal to that substring (sans the parentheses). There are many ways to do this, some of which are slight variants of the other answers. Here's another way that also allows for the possibility of multiple substrings within parentheses, picking up from #sawa's comments:
def doit(str, repl)
vars = []
str.gsub(/\(.*?\)/) {|m| vars << m[1..-2]; repl}, vars
end
new_str, vars = doit("This is (the string) I want to replace", '')
new_str # => => "This is I want to replace"
vars # => ["the string"]
new_str, vars = doit("This is (the string) I (really) want (to replace)", '')
new_str # => "This is I want"
vars # => ["the string", "really, "to replace"]
new_str, vars = doit("This (short) string is a () keeper", "hot dang")
new_str # => "This hot dang string is a hot dang keeper"
vars # => ["short", ""]
In the regex, the ? in .*? makes .* "lazy". gsub passes each match m to the block; the block strips the parens and adds it to vars, then returns the replacement string. This regex also works:
/\([^\(]*\)/
I've failed to work out how I can print and display white space characters as something that I can actually 'see'. So for example,
x = "123\n"
print x
I'd like the output to be
123\n
rather than
123
.
The above '.' represents the new line created by '\n'.
s = "abc\ndef"
p s
# >> "abc\ndef"
# it's equivalent to
puts s.inspect
# >> "abc\ndef"
You can do:
x = "123\n"
p x
#=> "123\n"
This method is documented in the Kernel module.
irb(main):003:0> x='123\n'
=> "123\\n"
irb(main):004:0> puts x
123\n
Works for me. Single quoted strings are unescaped, whilst double quoted strings are. To illustrate the difference, I've put the double quoted version below as well:
irb(main):001:0> x="123\n"
=> "123\n"
irb(main):002:0> puts x
123
=> nil
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.