这更像是一个 Ruby
问题,而不是 Rails
。
函数签名:
def create_table(table_name, comment: nil, **options)
...
end
用法:
create_table(:suppliers) do |t|
t.string :name, limit: 60
# Other fields here
end
鉴于 create_table
的函数签名,用法如何映射到它?
例如,
:suppliers
映射到 table_name
,block
如何映射到函数签名?
我还了解 *
是一个接受 x
个参数的 splat。
**
是一个 double splat(我认为),它接受 x
个哈希值(即键、值对)。
所以我不确定 **options
是否与 block
的传递有关。
最佳答案
每个 Ruby 方法还采用签名中不需要的隐式 block 参数。如果您研究create_table
的方法主体,您会发现:yield td if block_given?
这意味着:如果给定(或提供)了一个 block ,请使用 td
局部变量作为 block 参数(在您的代码中为 t
)来调用隐式 block 。示例)。
只要您不需要直接访问提供的 block ,就不需要将该 block 作为方法参数。如果您需要它,可以将其声明为方法参数,如下所示:
def create_table(table_name, comment: nil, **options, &block)
# do something with block
end
您也可以使用显式方法 block 参数并调用 block.call(td)
,而不是使用隐式方法 block 参数并调用 yield td
。这两者之间的 ruby 实现有所不同,yield 可能总是更快。
你是对的:*args
用于 splat 参数,其中 args
将是方法主体中的参数数组。 **kwargs
(或此处的 **options
)用于关键字参数,其中 kwargs
(或 options
)将是方法主体中参数的哈希值。
关于ruby-on-rails - Rails create_table 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44743793/