Neil
Neil

Reputation: 5178

Ruby Default Arguments: Static or Dynamic?

Are default arguments in ruby methods static? This matters when default arguments are meant to be a dynamic date, such as Date.today. Consider the following example in a rails application:

class User < ApplicationRecord

  def eligible_to_vote?(date_of_interest = Date.today)
    p date_of_interest
  end

end

Will the default date_of_interest date always be the the same, static date from when I started the rails server?

Or: will it always dynamically grab "today's date" within the context of the date that the eligible_to_vote? method was called?

I know the following would for sure dynamically grab Date.today:

# Always dynamically sets `date` variable when no argument passed in
class User < ApplicationRecord

  def eligible_to_vote?(date_of_interest = nil)
    date = date_of_interest.present? ? date_of_interest : Date.today
    p date_of_interest
  end

end

What I'm mostly interested in is if default method arguments are dynamically generated or not. Whatever the answer is, it would be nice to have some official reference to answer this question as well. Thanks!

Upvotes: 5

Views: 1774

Answers (3)

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369458

What I'm mostly interested in is if default method arguments are dynamically generated or not.

It would be trivially easy to test this:

def are_default_arguments_evaluated_every_time?(optional_parameter = puts('YES!')) end

are_default_arguments_evaluated_every_time?
# YES!

are_default_arguments_evaluated_every_time?
# YES!

If default arguments were evaluated at method definition time, this would print YES! only once, and before calling the method. If default arguments were evaluated only on the first call and then cached, this would print YES! only once, when the method first gets called.

Whatever the answer is, it would be nice to have some official reference to answer this question as well.

This is specified in section §13.3.3 Method invocation, step h), sub-step 7), sub-sub-step i) of the ISO Ruby Language Specification.

Upvotes: 7

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

It is dynamic because Ruby is interpreted, not compiled language.

✎ require 'date'
✎ def test param = DateTime.now
    puts param
  end
✎ 3.times { test; sleep(1) }
2018-12-14T18:10:08+01:00
2018-12-14T18:10:09+01:00
2018-12-14T18:10:10+01:00

Upvotes: 4

oren
oren

Reputation: 3209

it's not static, Date.today is evaluated every time.

Take for example:

def foo(some_var = boo)
  p some_var
end

def boo
  p "this is boo"
  Date.today
end

When you run today

foo 
# "this is boo"
# Fri, 14 Dec 2018
foo 
# "this is boo"
# Fri, 14 Dec 2018

When you run tomorrow

foo 
# "this is boo"
# Fri, 15 Dec 2018

Upvotes: 0

Related Questions