Sam 山
Sam 山

Reputation: 42865

Ruby: Passing optional objects to method

Class TShirt

def size(suggested_size)
  if suggested_size == nil
   size = "please choose a size"
  else
   size = suggested_size
  end
end
end 

tshirt = TShirt.new
tshirt.size("M")

== "M"

tshirt = TShirt.new
tshirt.size(nil)

== "please choose a size"

What is a better way to have optional objects in a method? Procs?

Upvotes: 0

Views: 816

Answers (3)

Awgy
Awgy

Reputation: 1082

Default values may be what you're looking for:

def size(suggested_size="please choose a size") 

You can find some more information about default values over at wikibooks. They also go over variable length argument lists and the option of passing in a hash of options to the method, both of which you can see in a lot of Rails code...

Variable Argument List

File vendor/rails/activerecord/lib/active_record/base.rb, line 607:

def find(*args)
  options = args.extract_options!
  validate_find_options(options)
  set_readonly_option!(options)

  case args.first
    when :first then find_initial(options)
    when :last  then find_last(options)
    when :all   then find_every(options)
    else             find_from_ids(args, options)
  end
end

Options Hash

File vendor/rails/activerecord/lib/active_record/base.rb, line 1361:

def human_attribute_name(attribute_key_name, options = {})
  defaults = self_and_descendants_from_active_record.map do |klass|
    "#{klass.name.underscore}.#{attribute_key_name}""#{klass.name.underscore}.#{attribute_key_name}"
  end
  defaults << options[:default] if options[:default]
  defaults.flatten!
  defaults << attribute_key_name.humanize
  options[:count] ||= 1
  I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => [:activerecord, :attributes]))
end

Object Attributes

If you are looking to have optional attributes in an object, you can write a getter and setter method in your class:

Class TShirt
  def size=(new_size)
    @size = new_size
  end

  def size
    @size ||= "please choose a size"
  end
end

Then you could just call use tshirt.size="xl" and tshirt.size on an instance of your TShirt class.

Upvotes: 5

JHurrah
JHurrah

Reputation: 1988

your code could also have been writen like this:

class TShirt
  def size(suggested_size)
    suggested_size ||= "please choose size" 
  end
end

x ||= "oi" is the same as x = "oi" if x.nil?

Upvotes: 1

Chuck
Chuck

Reputation: 237040

You can use default values for arguments (def size(suggested_size = nil)) or use a variable argument list (def size(*args)).

Upvotes: 2

Related Questions