Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中的代码块如何知道哪个变量属于对象的某个方面?_Ruby - Fatal编程技术网

Ruby中的代码块如何知道哪个变量属于对象的某个方面?

Ruby中的代码块如何知道哪个变量属于对象的某个方面?,ruby,Ruby,考虑以下几点: (1..10).inject{|memo, n| memo + n} 问题: n怎么知道它应该存储从1到10的所有值?我很困惑Ruby是如何理解n可以立即自动与(1..10)关联的,而memo就是memo 我知道Ruby代码块与C或Java代码块不同——Ruby代码块的工作方式有点不同。我不知道竖直的管道“|”之间的变量如何自动分配给对象的各个部分。例如: hash1 = {"a" => 111, "b" => 222} hash2 = {"b" => 333

考虑以下几点:

(1..10).inject{|memo, n| memo + n}
问题:

n怎么知道它应该存储从1到10的所有值?我很困惑Ruby是如何理解n可以立即自动与(1..10)关联的,而memo就是memo

我知道Ruby代码块与C或Java代码块不同——Ruby代码块的工作方式有点不同。我不知道竖直的管道“|”之间的变量如何自动分配给对象的各个部分。例如:

hash1 = {"a" => 111, "b" => 222}
hash2 = {"b" => 333, "c" => 444}
hash1.merge(hash2) {|key, old, new| old}
“| key,old,new |”如何以这样的方式自动分配自己:当我在代码块中键入“old”时,它会自动意识到“old”是指旧的散列值?我从来没有给任何东西加上“old”,只是声明了它。有人能解释一下这是怎么回事吗

备忘录就是备忘录

“只是备忘录”是什么意思
memo
n
获取
inject
传递的任何值。它的实现是将accumulator/memo作为第一个参数传递,将current collection元素作为第二个参数传递

“|键、旧键、新键”如何自动分配它们自己

他们不“分配自己”<代码>合并分配它们。或者更确切地说,将这些值(键、旧值、新值)按该顺序作为块参数传递

如果你改写

hash1.merge(hash2) {|foo, bar, baz| bar}
它仍能像以前一样正常工作。参数名称[此处]没有任何意义。重要的是实际值

备忘录就是备忘录

你什么意思,“只是备忘录”
memo
n
获取
inject
传递的任何值。它的实现是将accumulator/memo作为第一个参数传递,将current collection元素作为第二个参数传递

“|键、旧键、新键”如何自动分配它们自己

他们不“分配自己”<代码>合并分配它们。或者,将这些值(键、旧值、新值)按该顺序作为块参数传递

如果你改写

hash1.merge(hash2) {|foo, bar, baz| bar}

它仍能像以前一样正常工作。参数名称[此处]没有任何意义。重要的是实际值。

块的参数由方法定义确定。
reduce/inject
的定义是重载的()并在C中定义的,但是如果您想定义它,可以这样做(注意,对于实际的
reduce
定义,这并不涵盖所有重载情况):

此方法定义确定要为
memo
element
使用哪些值,并按特定顺序调用
blk
变量(传递给方法的块)

但是,请注意,块与常规方法不同,因为它们不检查参数的数量。例如:(注意,此示例显示了
yield
的用法,这是传递块参数的另一种方式)

您还可以在运行块时使用解构来定义变量,例如,如果您想通过哈希
减少
,您可以执行以下操作:

# this just copies the hash
{a: 1}.reduce({}) { |memo, (key, val)| memo[key] = val; memo }
module Enumerable
  def inject(memo)
    each do |el|
      memo = yield memo, el
    end
    memo
  end
end

其工作原理是,对散列调用
reduce
,隐式地调用
到a
,从而将其转换为元组列表(例如
{a:1}.to_a=[[:a,1]]
reduce
将每个元组作为第二个参数传递给块。在调用块的地方,元组被分解为单独的键和值变量。

块的参数由方法定义确定。
reduce/inject
的定义是重载的()并在C中定义的,但是如果您想定义它,可以这样做(注意,对于实际的
reduce
定义,这并不涵盖所有重载情况):

此方法定义确定要为
memo
element
使用哪些值,并按特定顺序调用
blk
变量(传递给方法的块)

但是,请注意,块与常规方法不同,因为它们不检查参数的数量。例如:(注意,此示例显示了
yield
的用法,这是传递块参数的另一种方式)

您还可以在运行块时使用解构来定义变量,例如,如果您想通过哈希
减少
,您可以执行以下操作:

# this just copies the hash
{a: 1}.reduce({}) { |memo, (key, val)| memo[key] = val; memo }
module Enumerable
  def inject(memo)
    each do |el|
      memo = yield memo, el
    end
    memo
  end
end

其工作原理是,对散列调用
reduce
,隐式地调用
到a
,从而将其转换为元组列表(例如
{a:1}.to_a=[[:a,1]]
reduce
将每个元组作为第二个参数传递给块。在调用块的地方,元组被分解为单独的键和值变量。

这里只是为了简化一些其他好的答案:

如果您正在努力理解块,一种简单的方法是将它们视为您正在创建和执行的原始临时方法,管道字符
|memo |
之间的值只是参数签名

参数背后没有特殊的概念,它们只是为您调用的方法传递变量而存在,就像用参数调用任何其他方法一样。与方法类似,参数是块范围内的“局部”变量(这有一些细微差别,取决于调用块时使用的语法,但我离题了,这是另一回事)

您将块传递给的方法只是调用这个“临时方法”,并将参数传递给它。就像通常调用方法一样,有一些细微的区别,比如没有“必需”参数。如果您没有定义任何要接收的参数,它将很高兴地不传递它们,而不是引发
ArgumentError
。同样,如果您为块定义了太多的参数而无法接收,那么它们将被忽略