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
Related
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
How to get a value from a string e.g
search_params[:price] = "1460,4500"
How can I get the first number into one variable and second into a different variable?
Did you mean this??:
first_price, second_price = search_params[:price].split(',')
You can use split method
irb(main):002:0> price = "1460,4500"
=> "1460,4500"
irb(main):003:0> price.split(',')
=> ["1460", "4500"]
irb(main):004:0> a, b = price.split(',')
=> ["1460", "4500"]
irb(main):005:0> a
=> "1460"
irb(main):006:0> b
=> "4500"
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
I've just seen this expression in a Ruby/Rails app:
def method(a, b = nil, &c)
c ||= ->(v) { v }
I understand the first part, but not the ->() { ... } syntax. What does it mean?
The variable names have been changed for briefness. I tried searching, but the non-alphanumeric characters are obviously a nightmare for SEO.
It is a lambda literal. Put the block variables inside () and the body inside {}.
->(x, y){x + y}
In the example, ->(v){v} takes a single argument v and returns it, in other words, it is an identity function. If a block is passed to method, then that is assigned to c. If not, the identity function is assigned to c as default.
That is a lambda literal, introduced in Ruby 1.9:
irb> l = ->(v) { v }
# => #<Proc:0x007f4acea30410#(irb):1 (lambda)>
irb> l.call(1)
# => 1
It is equivalent to write:
irb> l = lambda { |v| v }
# => #<Proc:0x00000001daf538#(irb):1 (lambda)>
In the example you posted it is used to provide a default block to the method when none is specified, consider this:
def method(a, &c)
c ||= ->(v) { v }
c.call(a)
end
method(1)
# => 1
method(1) { |v| v * 2 }
# => 2
9.3 I'm getting a strange behaviour and I cannot understand why:
s = self.shopify_p
s.title
=> "Disco (Wholesale)"
Right now I'd like to have a new variable with the content of s.title without the " (Wholesale)" part.
So I do the following:
original_title = s.title
=> "Disco (Wholesale)"
original_title[" (Wholesale)"] = ""
=> ""
Now if I do:
original_title
=> "Disco"
Which is ok but the strange thing is that it seems that the last string replace affected even the original s variable:
s.title
=> "Disco"
I really cannot understand this...can you tell me what is happening here?
s.title should still be "Disco (Wholesale)"...or not?
It is the same because you're accessing the same object.
irb(main):006:0> x = "aaaa"
=> "aaaa"
irb(main):007:0> y = x
=> "aaaa"
irb(main):008:0> x.object_id
=> 70358166435920
irb(main):009:0> y.object_id
=> 70358166435920
irb(main):010:0>
What you could do instead is
original_title = s.title.gsub(" (Wholesale)","")
After original_title = s.title both original_title and s.title reference the same object.
To actually copy the string either use Object#dup:
original_title = s.title.dup
dup → an_object
Produces a shallow copy of obj…
or String.new:
original_title = String.new(s.title)
new(str="") → new_str
Returns a new string object containing a copy of str.
Variables in ruby reference the objects they point to rather than copying them by default. So, if you change the underlying object, any changes will show up in any variables that contain a reference to that object.
If a, b, c and d all point to the same object, changes to any will "change" (be visible through) all of them.
a b c
\ | /
Object
|
d
If you want to keep your original value you'll need to somehow create a new variable.
irb(main):001:0> a = "Foo"
=> "Foo"
irb(main):002:0> b = a
=> "Foo"
irb(main):003:0> a << " Bar"
=> "Foo Bar"
irb(main):004:0> b
=> "Foo Bar"
irb(main):005:0> a
=> "Foo Bar"
irb(main):006:0> a += " Baz"
=> "Foo Bar Baz"
irb(main):007:0> a
=> "Foo Bar Baz"
irb(main):008:0> b
=> "Foo Bar"
For your case #wlad's gsub (note that he didn't use gsub!) suggestion seems like a good one.
original_title = s.title.gsub(" (Wholesale)","")