Assign a variable only if not zero

I have @obj.items_per_page , which is at the beginning of 20 , and I want the method below to assign a value to it only if many_items not nil :

 def fetch_it_baby (many_items = nil) @obj.items_per_page = many_items 

With the code above, even if many_items is nil , @obj.items_per_page stays at 20 . What for? And is this "good" coding? Shouldn't I use something like

 @obj.items_per_page = many_items || @obj.items_per_page 

Or is there a third way? I do not feel absolutely comfortable anyway.

+8
source share
6 answers

The style that I usually see is as follows:

 @obj.items_per_page = many_items if many_items 

It uses an inline condition, avoiding negative or double negative conditions.

+8
source

Even if many_items equals nil @ obj.items_per_page stays at level 20

It sounds as if the @obj class has its own modifier method items_per_page= , which only updates the value if the new value is not nil . This is not standard Ruby. For example, given this definition:

 class Demo attr_accessor :items_per_page end 

I get the following:

 irb(main):005:0> demo = Demo.new #=> #<Demo:0x007fb7b2060240> irb(main):006:0> demo.items_per_page = 20 #=> 20 irb(main):007:0> demo.items_per_page #=> 20 irb(main):008:0> demo.items_per_page = nil #=> nil irb(main):009:0> demo.items_per_page #=> nil 

As for your example, I would probably write it like this:

 @obj.items_per_page = many_items unless many_items.nil? 
+10
source

I suggest the following, as it makes it clear that you have a default value for the assignment if the caller did not specify many_items in the call:

 def function(argument = nil) variable = argument || 20 ... end 

However, since you indicated that the assignment is only performed if the value is not nil , you need to check the nil value, otherwise you will skip the assignment if the value was false . If you really need this case, then the solution is longer:

 def function(argument = nil) variable = argument.nil? ? 20 : argument ... end 
+9
source

You can use &&= (just as ||= used to assign only if nil or false)

 > a = 20 # => 20 > a &&= 30 # => 30 > a # => 30 > a = nil # => nil > a &&= 30 # => nil > a = false # => false > a &&= 30 # => false > a = {} # => {} > a &&= 30 # => 30 
+9
source

The new-alexandria answer is my transition, but another "third way" is to use ternary :

 class Demo attr_accessor :items_per_page end many_items = 100 @obj = Demo.new @obj.items_per_page = 20 #=> 20 @obj.items_per_page = !many_items.nil? ? 30 : nil #=> 30 
0
source

I use Rails and I have a similar need.

You can define a method for your model:

 class Gift < ApplicationRecord def safe_set(attribute, value) return if value.nil? send("#{attribute}=", value) end end 

So what can you do

 g = Gift.new g.colour = 'red' g.safe_set(:colour, nil) g.colour -> 'red' g.safe_set(:colour, 'green') g.colour -> 'green' 
0
source

Source: https://habr.com/ru/post/955013/


All Articles