Ruby Check condition if a string include multi-different strings? - ruby-on-rails

I am newbie to Ruby. Are there any better ways to write this:
if (mystring.include? "string1") || (mystring.include? "string2") ||
(mystring.include? "string3")

Yes, as below :
if %w(string1 string2 string3).any? { |s| my_string.include? s }
# your code
end
Here is the documentation : Enumerable#any?
Passes each element of the collection to the given block. The method returns true if the block ever returns a value other than false or nil. If the block is not given, Ruby adds an implicit block of { |obj| obj } that will cause any? to return true if at least one of the collection members is not false or nil.
Here is another way ( more fastest) :
[13] pry(main)> ary = %w(string1 string2 string3)
=> ["string1", "string2", "string3"]
[14] pry(main)> Regexp.union(ary)
=> /string1|string2|string3/
[15] pry(main)> "abbcstring2"[Regexp.union(ary)]
=> "string2"
[16] pry(main)> "abbcstring"[Regexp.union(ary)]
=> nil
Just read Regexp::union and str[regexp] → new_str or nil .

Well, you could always use a regular expression here (risking another jwz quote :)
if mystring =~ /string1|string2|string3/
...
end

Related

Ruby access hash value by a variable

Let's consider this as our hash c = {:test => {:foo => true}}
Normally, if we would like to print value of foo, we would access the hash like this c[:test][:foo] but I would like to access it dynamically based on my variable.
Therefore, let's consider the following variable path = [[:test],[:foo]].
How do I access the value true now? I have tried c[path] but it just says nil. What am I missing?
You can make use of dig. You can check the doc of dig here Hash#dig
c = { :test => { :foo => true } }
c[:test][:foo]
#=> true
c.dig(:test, :foo)
#=> true
path = [:test, :foo]
c.dig(*path)
#=> true
You just need to pass the hierarchy
Note: The * before path in c.dig(*path) is reffered as splat operator
Old good recursive Ruby 1.9+ solution:
hash = {:test => {:foo => true}}
path = [[:test],[:foo]]
path.flatten.reduce(hash) { |h, p| h[p] }
#⇒ true
Or, as #Stefan suggested in comments:
path.reduce(hash) { |h, (p)| h[p] }
# or even
path.reduce(hash) { |h, p| h[p.first] }
More defensive:
path.flatten.reduce(hash) { |h, p| h.nil? ? nil : h[p] }

Is there a shorthand way to check for presence before assigning a variable in ruby?

is there a shorter way to do this (considering a is already set to some value):
a = b if b.present?
I may have come across a way to do this before, but don't remember.
Just a = b if b.present? on its own is functionally equivalent to:
if b.present?
a = b
else
a = nil
end
so you could use Object#presence:
presence()
Returns the receiver if it's present otherwise returns nil. object.presence is equivalent to
object.present? ? object : nil
like this:
a = b.presence
If a already has a value and you're really saying:
a = something_interesting
a = b if b.present?
then you could say:
a = b.presence || something_interesting
if b is some complex expression that you want to evaluate just once, you could use
a = b.presence || a
you could do this
a = b if !b.nil?
or
a = b if b
or
a = b if b != nil
The thing about present? is it protects you against the trap of empty arrays, hashs, and other collections. So these will work if you are not concerned about an empty collection.
You can use ||= operator, but it depends on of what you want your code to do. This operator assigns the value of b to a if b is not nil.For example, if a = 5 and perform the following operation a ||= b value of b will be assigned to a only if b is not nil, but if a was not previously declared value of a will be nil for this code a ||= b.
EXAMPLES:
irb(main):001:0> b = nil
=> nil
irb(main):002:0> a ||= b
=> nil
irb(main):003:0> b = 5
=> 5
irb(main):004:0> a ||= b
=> 5
irb(main):005:0> a ||= nil
=> 5
||= operator is what you are looking for. It checks if the operand is nil or present before assigning a value. If present doesn't assign, if nil or undefined will assign the value.
[1] pry(main)> a
NameError: undefined local variable or method `a' for main:Object
from (pry):1:in `__pry__'
[2] pry(main)> a ||= 100
=> 100
[3] pry(main)> a = nil
=> nil
[4] pry(main)> a ||= 100
=> 100
[5] pry(main)> a ||= 200
=> 100

What is Returned in Ruby if the Last Statement Evaluated is an If Statement

My understanding is that ruby returns the last statement evaluated in a function. What if the function ends with an if statement that evaluates to false
def thing(input)
item = input == "hi"
if item
[]
end
end
puts thing("hi").class #> Array
puts thing("not hi").class #> NilClass
I like this functionality (returning nil if the statement is false), but why isn't false returned (from the assignment to item)?
If your if statement doesn't result in any code being run, it returns nil, otherwise it returns the value of the code that was run. irb is a good tool to experiment with such stuff:
irb(main):001:0> i = if false then end
=> nil
irb(main):002:0> i = if true then end
=> nil
irb(main):007:0> i = if false then "a" end
=> nil
irb(main):008:0> i = if false then "a" else "b" end
=> "b"
The return value of an if expression is the value of the clause that was evaluated, not of the condition. In case no clause was evaluated (if without else), nil is returned:
irb(main):001:0> x = if false
irb(main):002:1> []
irb(main):003:1> end
=> nil
irb(main):004:0> x
=> nil
irb(main):005:0>

ror, how to make a regex dynamic?

given this:
if (params[:to].to_s =~ (/^r\+.*#site.com$/)) == nil
How can I make site.com dynamic to: #{SITE_CONFIG['mail_host']}
I tried
if (params[:to].to_s =~ (/^r\+.*##{SITE_CONFIG['mail_host']}$/)) == nil
Which did not work.. ideas?
In ruby you can create the regexp from a string representation using Regexp.new:
if (params[:to].to_s =~ Regexp.new("^r\\+.*##{Regexp.quote(SITE_CONFIG['mail_host'])}$")) == nil
Define "not work", regexes can contain interpolated strings:
pry(main)> foo = "wat"
=> "wat"
pry(main)> "ohai wat kthxbai" =~ /#{foo}/
=> 5
pry(main)> foo = "nar"
=> "nar"
pry(main)> "ohai wat kthxbai" =~ /#{foo}/
=> nil
pry(main)> /#{foo}/
=> /nar/

Simplify Assignment in Ruby on Rails

I just want to assign the value of variable B to variable A only if B is not nil.
And I want to simplify the code as possible.
So I found the one.
A = B if B
But variable name is long such as data[:Symbol1][:Symbol2]... , anyhow same variable name is duplicated.
Can anybody help me with simplifying this code?
You might try the presence method.
Your code would look like
A = B.presence
Example of it in action:
[1] pry(main)> b = nil
=> nil
[2] pry(main)> a = b.presence
=> nil
[3] pry(main)> a
=> nil
[4] pry(main)> b = 'foo'
=> "foo"
[5] pry(main)> a = b.presence
=> "foo"
[6] pry(main)> a
=> "foo"
I'd say you need A = B || A.
The || operator evaluates and returns the first non-false operand. If B is "truthy", it will return B (and assign it to A). If B is false, A will just be assigned itself.
2 simple ways:
a = b.presence || a
Or
a = b || a

Resources