Написание метода, который принимает параметры в разных строках в Ruby - PullRequest
3 голосов
/ 03 февраля 2011

Работая с Rails, я увидел, что можно вызывать такие методы.

lot = Lot.new do |u|
    u.grade_id = grade.id
    u.company_id = company.id
    u.type_id = type.id
    u.sale_id = sale.id
    u.quantity = lot[6]
    u.price = lot[3]
    u.info = lot[4]
    u.remark = lot[5]
end

Как видите, я передаю параметры по разным строкам.

Мне нужно написать несколько методов, которые принимают много аргументов, и подумали, что было бы намного лучше, если бы я мог вызывать свой метод следующим образом.Может ли кто-нибудь показать мне, как писать методы, которые принимают аргументы подобным образом?Ссылка на какое-нибудь руководство / документацию будет очень полезной.Это то, что они называют блоками кода в Ruby?

Ответы [ 3 ]

4 голосов
/ 03 февраля 2011

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

Этот код

lot = Lot.new do |u|
    u.grade_id = grade.id
    u.company_id = company.id
end

можно записать как

lot = Lot.new
lot.grade_id = grade.id
lot.company_id = company.id

Во втором примере блок не используется.

Если вы хотите, чтобы ваш объект принимал блоки при инициализации, добавьте следующую строку кода в ваш файл initialize.

yield self if block_given?

Вот пример

class MyObject
  def initialize
    # ...
    yield self if block_given?
  end
end
0 голосов
/ 03 февраля 2011

Погружаясь глубже, я думаю, вы бы выиграли от более глубокого понимания "блоков" в Ruby (которые отличаются от общих терминов программирования "блок кода" или "блок кода").

Притворятьсяна мгновение, когда на самом деле работал следующий (недопустимый) код Ruby:

def add10( n )
  puts "#{n} + 10 = #{n+10}"
end

def do_something_with_digits( method )
  1.upto(9) do |i|
    method(i)
  end
end

do_something_with_digits( add10 )
#=> "1 + 10 = 11"
#=> "2 + 10 = 12"
...
#=> "9 + 10 = 19"

Хотя этот код недопустим, его намерение - передать некоторый код методу и запустить этот метод - в Ruby возможноразными способами.Один из таких способов - «Блоки».

Блок в Ruby очень и очень похож на метод: он может принимать некоторые аргументы и запускать код для них.Всякий раз, когда вы видите foo{ |x,y,z| ... } или foo do |x,y,z| ... end, это блоки, которые принимают три параметра и запускают на них .... (Вы можете даже увидеть, что вышеприведенному методу upto передается блок.)

Поскольку блоки являются особой частью синтаксиса Ruby, каждому методу разрешено передаватьблок.Независимо от того, использует ли метод , блок зависит от метода.Например:

def say_hi( name )
  puts "Hi, #{name}!"
end

say_hi("Mom") do
  puts "YOU SUCK!"
end
#=> Hi, Mom!

Приведенному выше методу передается блок, который готов выдать оскорбление, но, поскольку метод никогда не вызывает блок, печатается только симпатичное сообщение.Вот как мы вызываем блок из метода:

def say_hi( name )
  puts "Hi, #{name}!"
  if block_given?
    yield( name )
  end
end

say_hi("Mridang") do |str|
  puts "Your name has #{str.length} letters."
end
#=> Hi, Mridang!
#=> Your name has 7 letters.

Мы используем block_given?, чтобы увидеть, был ли передан блок или нет.В этом случае мы передали аргумент обратно в блок;Ваш метод решает, что передать блоку.Например:

def say_hi( name )
  puts "Hi, #{name}!"
  yield( name, name.reverse ) if block_given?
end

say_hi("Mridang"){ |str1, str2| puts "Is your name #{str1} or #{str2}?" }
#=> Hi, Mridang!
#=> Is your name Mridang or gnadirM?

Это просто соглашение (и хорошее, и то, которое вы хотите поддерживать) для некоторых классов для передачи только что созданного экземпляра в блок.

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

0 голосов
/ 03 февраля 2011

Вам нужно передать блок в вашем методе.

def initialize(&block)
  yield self
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...