Ruby: how to insert a conditional into a string concatenation - ruby

In a string concatenation, is it possible to include a conditional directly into the statement?
In the example below, I want "my dear" to be concatenated only if the dear list is not empty.
dear = ""
string = "hello" + " my dear" unless dear.empty? + ", good morning!"
But the result is an error: undefined method '+' for true
I know the alternative would be to define an additional variable before this statement but I would like to avoid this.

It is easier and more readable with interpolation instead of concatenation:
dear = ""
string = "hello#{ ' my dear' unless dear.empty? }, good morning!"

In this case, you would be better off using ternary operators.
string = "hello" + (dear.empty? ? "" : " my dear") + ", good morning!"
The syntax goes like
condition ? if true : if false

Here is something cutie
dear = ""
"hello%s, good morning!" % (' my dear' unless dear.empty?)
# => "hello, good morning!"
dear = "val"
"hello%s, good morning!" % (' my dear' unless dear.empty?)
# => "hello my dear, good morning!"

I will share my solution.
2.7.0 :040 > dear = ""
2.7.0 :041 > string = "hello #{dear.empty? ? "World" : dear}, good morning!"
2.7.0 :042 > string
=> "hello World, good morning!"
2.7.0 :043 > dear = "Test"
2.7.0 :044 > string = "hello #{dear.empty? ? "World" : dear}, good morning!"
2.7.0 :045 > string
=> "hello Test, good morning!"
2.7.0 :046 >

Related

How to replace single blackslash in ruby

I have been trying something like this to replace blackslash with a word:
str ="\"
str.gsub!("\", "\add")
no luck so far. What am I doing wrong? Thanks
The syntax highlighting on Stack Overflow suggests the problem. Your initial backslash isn't escaped!
str.gsub("\\","\\add")
edit for clarification:
2.2.0 :002 > str = "\\"
=> "\\"
2.2.0 :003 > str.gsub("\\","\\add")
=> "\\add"
Try this code
str = "\\"
str.gsub!("\\", "add")
print str
"\" does not exist in a ruby string
str ="RU\BY"
puts str
will print RUBY
You only can use "\\" so the answer is str.gsub!("\\","\\add")

Ruby string manipulation, remove first 3 characters and add them to the end of the string

mystring = "svn-myapplication" or mystring = "git-myapplication"
My desired output:
mystring = "myapplications(svn)"
mystring = "myapplication(git)"
Question: The first 3 characters of the string should be moved to the last with enclosed brackets and the "-" should be removed.
I tried to do something like this:
mystring.gsub('svn-','')+"(svn)" but svn might be git, so i want to use the first three characters to be moved to end with "-" removed and brackets enclosed
A regular expression with groups would work well:
mystring.gsub(/^([a-z]+)-(\w+)/, '\2(\1)')
Lets rock'n'roll :)
mystring = "svn-myapplication"
mystring.split('-').rotate.join('(') + ')'
You could use e regular expression but the simplest solution is as follows
mystring = "svn-myapplication"
puts "#{mystring[4..-1]}(#{mystring[0..2]})"
gives
myapplication(svn)
You can use the [] method of Ruby's String class for this:
mystring = "svn-myapplication"
mystring = "#{mystring[4..-1]}(#{mystring[0,3]})"
You can try something like this in irb
1.9.3-p362 :001 > mystring = "svn-myapplication"
1.9.3-p362 :002 > mystring.gsub(mystring[0,3]+'-','')+(mystring[0,3])
I was going to submit this but, at least I can see how to do it better!
def test(s = '')
match = /\w+-/.match(s).to_s
match = match[0..-2]
s.gsub!(/\w+-/, '')
s << "(#{match})"
end # of test

How to print a string with a backward slash in Ruby

I have a string str = "xyz\123" and I want to print it as is.
The IRB is giving me an unexpected output. Please find the same below:-
1.9.2p290 :003 > str = "xyz\123"
=> "xyzS"
1.9.2p290 :004 >
Any ideas on how can I get IRB to print the original string i.e. "xyz\123".
Thank you..
UPDATE :
I tried escaping it , but it doesn't seem to be that simple for some reason. Please find below my trials with the same:
1.9.2p290 :004 > str = "xyz'\'123"
=> "xyz''123"
1.9.2p290 :005 > str = "xyz'\\'123"
=> "xyz'\\'123"
1.9.2p290 :006 > str = "xyz'\\\'123"
=> "xyz'\\'123"
1.9.2p290 :007 >
UPDATED answer:
escape token '\' is always working in plain ruby code, but not always working in "ruby console". so I suggest you write a unit test:
# escape_token_test.rb
require 'test/unit'
class EscapeTokenTest < Test::Unit::TestCase
def test_how_to_escape
hi = "hi\\backslash"
puts hi
end
end
and you will get result as:
hi\backslash
and see #pst's comment.
The backslash character is an escape character. You may have seen "\n" be used to display a new line, and that is why. "\123" evaulates the ASCII code for 83, which is "S". To print a backslash use 2 backslashes. So you could use str = "xyz\\123".
How to print a backslash?
Use 2 backslashes, e.g. "xyz\\123"
Why does "xyz\123" evaluate to "xyzS"?
In a double-quoted string, \nnn is an octal escape.
Thomas, D. (2009) Programming Ruby, p.329
So, octal 123
= (64 * 1) + (8 * 2) + 3
= decimal 83
= ASCII S
It's simple ... try dump function:
mystring = %Q{"Double Quotes"}
p mystring.dump
=> "\"\\\"Double Quotes\\\"\""
p mystring
=>"\"Double Quotes\""

simplest way to check for just spaces in ruby

So I know in ruby that x.nil? will test if x is null.
What is the simplest way to test if x equals ' ', or ' '(two spaces), or ' '(three spaces), etc?
Basically, I'm wondering what the best way to test if a variable is all whitespace?
If you are using Rails, you can simply use:
x.blank?
This is safe to call when x is nil, and returns true if x is nil or all whitespace.
If you aren't using Rails you can get it from the activesupport gem. Install with gem install activesupport. In your file either require 'active_support/core_ext to get all active support extensions to the base classes, or require 'active_support/core_ext/string' to get just the extensions to the String class. Either way, the blank? method will be available after the require.
"best" depends on the context, but here is a simple way.
some_string.strip.empty?
s =~ /\A\s*\Z/
Regex solution. Here's a short ruby regex tutorial.
If x is all whitespace, then x.strip will be the empty string. So you can do:
if not x.nil? and x.strip.empty? then
puts "It's all whitespace!"
end
Alternatively, using a regular expression, x =~ /\S/ will return false if and only if x is all whitespace characters:
if not (x.nil? or x =~ /\S/) then
puts "It's all whitespace!"
end
a = " "
a.each_byte do |x|
if x == 32
puts "space"
end
end
Based on your comment I think you can extend the String class and define a spaces? method as follows:
$ irb
>> s = " "
=> " "
>> s.spaces?
NoMethodError: undefined method `spaces?' for " ":String
from (irb):2
>> class String
>> def spaces?
>> x = self =~ /^\s+$/
>> x == 0
>> end
>> end
=> nil
>> s.spaces?
=> true
>> s = ""
=> ""
>> s.spaces?
=> false
>>
s.include?(" ")
Examples:
s = "A B C D"
s.include?(" ") #=> true
s = "ABCD"
s.include?(" ") #=> false
Yet another :) string.all? { |c| c == ' ' }

What is the canonical way to trim a string in Ruby without creating a new string?

This is what I have now - which looks too verbose for the work it is doing.
#title = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?
Assume tokens is a array obtained by splitting a CSV line.
now the functions like strip! chomp! et. all return nil if the string was not modified
"abc".strip! # => nil
" abc ".strip! # => "abc"
What is the Ruby way to say trim it if it contains extra leading or trailing spaces without creating copies?
Gets uglier if I want to do tokens[Title].chomp!.strip!
I guess what you want is:
#title = tokens[Title]
#title.strip!
The #strip! method will return nil if it didn't strip anything, and the variable itself if it was stripped.
According to Ruby standards, a method suffixed with an exclamation mark changes the variable in place.
Update: This is output from irb to demonstrate:
>> #title = "abc"
=> "abc"
>> #title.strip!
=> nil
>> #title
=> "abc"
>> #title = " abc "
=> " abc "
>> #title.strip!
=> "abc"
>> #title
=> "abc"
Btw, now ruby already supports just strip without "!".
Compare:
p "abc".strip! == " abc ".strip! # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip # true
Also it's impossible to strip without duplicates. See sources in string.c:
static VALUE
rb_str_strip(VALUE str)
{
str = rb_str_dup(str);
rb_str_strip_bang(str);
return str;
}
ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
Update 1:
As I see now -- it was created in 1999 year (see rev #372 in SVN):
Update2:
strip! will not create duplicates — both in 1.9.x, 2.x and trunk versions.
There's no need to both strip and chomp as strip will also remove trailing carriage returns - unless you've changed the default record separator and that's what you're chomping.
Olly's answer already has the canonical way of doing this in Ruby, though if you find yourself doing this a lot you could always define a method for it:
def strip_or_self!(str)
str.strip! || str
end
Giving:
#title = strip_or_self!(tokens[Title]) if tokens[Title]
Also keep in mind that the if statement will prevent #title from being assigned if the token is nil, which will result in it keeping its previous value. If you want or don't mind #title always being assigned you can move the check into the method and further reduce duplication:
def strip_or_self!(str)
str.strip! || str if str
end
As an alternative, if you're feeling adventurous you can define a method on String itself:
class String
def strip_or_self!
strip! || self
end
end
Giving one of:
#title = tokens[Title].strip_or_self! if tokens[Title]
#title = tokens[Title] && tokens[Title].strip_or_self!
If you are using Ruby on Rails there is a squish
> #title = " abc "
=> " abc "
> #title.squish
=> "abc"
> #title
=> " abc "
> #title.squish!
=> "abc"
> #title
=> "abc"
If you are using just Ruby you want to use strip
Herein lies the gotcha.. in your case you want to use strip without the bang !
while strip! certainly does return nil if there was no action it still updates the variable so strip! cannot be used inline. If you want to use strip inline you can use the version without the bang !
strip! using multi line approach
> tokens["Title"] = " abc "
=> " abc "
> tokens["Title"].strip!
=> "abc"
> #title = tokens["Title"]
=> "abc"
strip single line approach... YOUR ANSWER
> tokens["Title"] = " abc "
=> " abc "
> #title = tokens["Title"].strip if tokens["Title"].present?
=> "abc"
If you want to use another method after you need something like this:
( str.strip || str ).split(',')
This way you can strip and still do something after :)
I think your example is a sensible approach, although you could simplify it slightly as:
#title = tokens[Title].strip! || tokens[Title] if tokens[Title]
Alternative you could put it on two lines:
#title = tokens[Title] || ''
#title.strip!
If you have either ruby 1.9 or activesupport, you can do simply
#title = tokens[Title].try :tap, &:strip!
This is really cool, as it leverages the :try and the :tap method, which are the most powerful functional constructs in ruby, in my opinion.
An even cuter form, passing functions as symbols altogether:
#title = tokens[Title].send :try, :tap, &:strip!
My way:
> (#title = " abc ").strip!
=> "abc"
> #title
=> "abc"
#title = tokens[Title].strip! || tokens[Title]
It's entirely possible i'm not understanding the topic, but wouldn't this do what you need?
" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"

Resources