Как решить, был ли задан необязательный аргумент в методе ruby - PullRequest
8 голосов
/ 03 января 2012

У меня есть метод с необязательным аргументом.Как я могу решить, был ли дан Аргумент или нет?

Я придумал следующие решения.Я задаю этот вопрос, так как я не полностью удовлетворен ни одним из них.Существует ли лучший вариант?

nil в качестве значения по умолчанию

def m(a= nil)
    if a.nil?
        ...
    end
end

Недостаток этого способа заключается в том, что нельзя решить, был ли задан аргумент или nil.

custom NoArgument в качестве значения по умолчанию

class NoArgument
end

def m(a= NoArgument.new)
    if NoArgument === a
        ...
    end
end

Можно ли определить, был ли указан nil, но такая же проблема существует для экземпляров NoArgument.

Оценкаразмер многоточия

def m(*a)
    raise ArgumentError if m.size > 1
    if m.size == 1
        ...
    end
end

В этом варианте всегда можно решить, был ли задан необязательный аргумент.Однако Proc#arity этого метода был изменен с 1 на -1 (не соответствует действительности, см. Комментарий).У него все еще есть недостаток: он хуже документируется и требует ручного вызова ArgumentError.

Ответы [ 2 ]

15 голосов
/ 03 января 2012

Jorg W Mittag имеет следующий фрагмент кода , который может делать то, что вы хотите:

def foo(bar = (bar_set = true; :baz))
  if bar_set
    # optional argument was supplied
  end
end
4 голосов
/ 03 января 2012

Как насчет

NO_ARGUMENT = Object.new

def m(a = NO_ARGUMENT)
    if a.equal?(NO_ARGUMENT)
        #no argument given
    end
end
...