#ruby #ruby-on-rails-3.1
#ruby #ruby-on-rails-3.1
Вопрос:
1) У меня есть метод
def self.createobj(api_key, amnt, commentstr, orderid, order_creation_date, orderfullfilmentdate)
.....
end
2) Я хочу создать error_str всех параметров, переданных этой функции…
2.1) Что-то вроде
errorstr = "api_key: " api_key.to_s " amnt: " amnt.to_s " commentstr: " commentstr.to_s " orderid: " orderid.to_s " order_creation_date: " order_creation_date.to_s " orderfullfilmentdate: " orderfullfilmentdate.to_s
2.2) Поэтому я создал другой метод
def self.get_params_str(a)
str = ""
a.each do |a|
str = str a.to_s
end
return str
end
2.3) Поэтому я вызываю этот новый метод из createobj. Что-то вроде
def self.createobj(api_key, amnt, commentstr, orderid, order_creation_date, orderfullfilmentdate)
errorstr = get_params_str(args)
.....
end
3) Но я получаю ошибку неопределенной локальной переменной или метода `args’ для #. Разве аргументы не должны иметь все параметры?
Пожалуйста, совет.
Ответ №1:
То, что вы пытаетесь сделать (пытаетесь использовать волшебную переменную с именем args, которая будет содержать все аргументы), не работает таким образом в Ruby.
Метод может иметь необязательные аргументы:
def my_method(*args)
....
# the array args will have 0 or more elements, depending on how many
# were in the method invocation.
end
Но если у метода есть определенные (обязательные) аргументы, как в вашем примере, то другого способа добраться до них нет.
Добавлено, если вы хотите изменить определение своего метода, чтобы использовать обходной путь для именованных аргументов, тогда аргументы будут поступать в виде ассоциативного массива, и затем вы можете отправить их на свой get_params_string
Или, что еще лучше, переопределите свой get_params_string
, чтобы использовать переменный список аргументов
def self.get_params_str(*a)
str = ""
a.each do |a|
str = str a.to_s
end
return str
end
# Then call it from your main method:
def self.createobj(api_key, amnt, commentstr, orderid,
order_creation_date, orderfullfilmentdate)
errorstr = get_params_str(api_key, amnt, commentstr, orderid,
order_creation_date, orderfullfilmentdate)
.....
end
Смотрите полезный пост
Ответ №2:
args
будет содержать параметры только в том случае, если ваше определение метода было чем-то вроде def self.createobj(*args)
. Без этого args
не определено.
Вам нужно будет вручную передать все параметры get_params_str
. Вам нужно будет передать их как массив, т.е. get_params_str([api_key, amnt, commentstr, ...])
Если вы не измените get_params_str
сигнатуру метода на def self.get_params_str(*a)
(которая помещает все параметры, переданные get_params_str
в один массив).
Ответ №3:
Как указано в других ответах, нет доступной переменной, подобной args
той, которая предоставляет имена аргументов для метода, однако, если вы используете Ruby 1.9.2 (я не могу подтвердить, существует ли она и в 1.9.1), у вас есть метод parameters
, поэтому вы можете сделать что-то вроде этого:
def foo(a, b, c)
errorstr = method(:foo).parameters.map{|p| "#{p.last}: #{eval p.last.to_s}" }.join(', ')
puts errorstr
end
foo(1, 2, 3) #=> a: 1, b: 2, c: 3
Комментарии:
1. 1 Итак
parameters
, это отражение именованных параметров? Умный.2. Я не знаю степени
parameters
, но, например, если вы попробуете этоdef test(a, *b, amp;blk) ; end
, вы получите[[:req, :a], [:rest, :b], [:block, :blk]]
, так что он не только даст вам имя в качестве символа, но и сообщит вам, требуется ли это, блок и т. Д.