Параметры метода в строку

#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]] , так что он не только даст вам имя в качестве символа, но и сообщит вам, требуется ли это, блок и т. Д.