Bryan Spence
Bryan Spence

Reputation: 133

Using ? in a method containing a variable

So i have the following as an IF statement to check validity of a discount code

if discount.present? && discount.usable?

I need to pass some extra info into the .usable to make some extra checks so i changed it to

if discount.present? && discount.usable(shopping_cart)?

However, rails throws a hissy fit when i do that - is there a way round that to keep the boolean result of what i'm trying to achieve?

Here is the usable method - i was forced to remove the ? at the end of all of these as well

def usable(shopping_cart)
    !has_expired? && !limit_used_up? && matches_product(shopping_cart)
end

def matches_product(shopping_cart)

if product_item_ids.present? 
    shopping_cart.shopping_cart_items.each do |item|
      if !product_item_ids.include? item.item_id
        return false
      else
        true
      end
    end
else
  true
end

Upvotes: 0

Views: 51

Answers (2)

chrismanderson
chrismanderson

Reputation: 4813

If the usable? method takes a shopping cart parameter, you can do

discount.usable?(shopping_cart)

The question mark is part of the method name so you need to write it out as such.

A larger note, there’s nothing special about a single “?” as part of a method name in Ruby. It is common style to end methods which return a Boolean with a question mark. This makes it more obvious that the method returns a bool. But there is nothing syntantatically special about the question mark. You could easily have a method which returns a bool without it, and a method that does not return a bool with it. (Though for style reasons, I would not recommend the latter.)

In some cases, people will alias the method name so you could have a method both with the mark and without it. In a method that takes a parameter and returns a bool, it can in some cases look nicer to be able to call it without the question mark in the middle. But again, that’s more of a personal preference than anything.

Upvotes: 2

EJAg
EJAg

Reputation: 3298

The ruby convention is to use "?" in methods that return boolean values. But itself is nothing special in a method definition. It's just part of the name.

You need to do

def usable?(shopping_cart)
    !has_expired? && !limit_used_up? && matches_product(shopping_cart)
end

Then you can call

discount.usable?(shopping_cart)

Upvotes: 3

Related Questions