0

I have this weird behavior of my helper and suspect is has something to do with Is Ruby pass by reference or by value?, can I ask for your help to explain the behavior?

views/xxx.html

helperA(@object.attribute_A)

helperA.rb

def helperA(object)
    if object == nil
       return 
    end 
    # do something if not nil 

However when nothing is passed into the helper(object does not have attribute_A), the 'if object == nil' doesn't catch the situation and continue running the code, which usually will cause error like "undefined method `length' for nil:NilClass" that's because of the later operation in helper.

My question is why is this happening?

ycl29
  • 3
  • 1
  • You can also use `object.nil?` or since this is tagged Rails, you can also use `object.blank?` to catch all falsy values such as `nil, 0, '', ' '` Also are you sure that `length` comes from `object` and not from another attribute? – dcangulo May 04 '22 at 03:00
  • 2
    `object == nil` isn't idomatically correct Ruby. Use `object.nil?` or just `if object` since everything except nil and false is truthy. – max May 04 '22 at 03:27
  • 2
    If `object` does not have `attribute_A` then wouldn't `@object.attribute_A` raise a `NoMethodError` exception? So what does `@object.attribute_A` actually do when `@object` does not have `attribute_A`? – mu is too short May 04 '22 at 04:58
  • agree with @muistooshort , looks like object.attribute_A is not raising an exception but returning something, and that something isn not nil. Once you fix that (make it return nil or raise exception) your example would work. – Joel Blum May 04 '22 at 05:19
  • thank you guys, I added a default value to the helper (helperA(object="") and catch ("") in the first line solved the issue. using object.blank? will work too. agree with @muistooshort and JoelBlum that I need to look into the object to really understand what'd happen while .attribute_A is called when .attribute_A is nil – ycl29 May 04 '22 at 05:57
  • _"when nothing is passed into the helper"_ – then Ruby won't call the method but instead raise an `ArgumentError` because the `object` argument is mandatory. In other words: if `helper` gets called, something _is_ being passed. You might want to inspect `object` within your helper to understand what it is. `p object` and / or `puts object.class` should get you started. – Stefan May 04 '22 at 06:54
  • Show your code where you would "pass nothing" to the function. You have to supply a parameter when calling this function (otherwise you get an exception), and there is no piece of data in the Ruby world which would be "nothing". Therefore, I don't understand what you are doing in your program. – user1934428 May 04 '22 at 08:49
  • BTW, it is important to use the right terminology with such tricky questions: Ruby does not have "attributes" (even though the methods named `attr_reader` and so on may mislead in believing that it has. If you do a `@object.attribute_A`, you are invoking a method named `attribute_A` on @object. If this method does not exist, you get an exception. If this method exists, it must return some value (it is not possible in Ruby to write _void_ methods which don't return a value). – user1934428 May 04 '22 at 08:53

1 Answers1

0
# set object to default as nil
def helperA(object = nil)
  return nil if object.nil? ## use object.blank? if you want empty strings, empty hashes and empty arrays to be caught in addition to nil

  # do something if not nil 
end

you can also do something with what you are passing into the input

helperA(@object&.attribute_A) # tells the function to treat the input as nil if the @object doesn't exist
alilland
  • 2,039
  • 1
  • 21
  • 42