编写一个在Ruby中的不同行上获取参数的方法

时间:2011-02-03 11:04:01

标签: ruby

在使用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 个答案:

答案 0 :(得分:4)

上面的例子没有传递任何参数。您只是调用一个方法并使用一个块来生成新创建的实例。

此代码

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

答案 1 :(得分:0)

您需要在方法中传递一个块。

def initialize(&block)
  yield self
end

答案 2 :(得分:0)

深入潜水,我认为你会受益于对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方法正在传递一个块。)

因为Blocks是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的答案,并帮助您在未来的编程过程中使用块。