Ruby 简单程序跟踪(产量-方法)
Ruby Simple Program Tracing (Yield - Method)
这是我根据有关 TeamTreeHouse ruby 轨道上的 Ruby 块的视频课程创建的代码,这是代码及其输出..
我的代码:
def get_name(prompt, &block)
print prompt + ": "
name = gets.chomp
print "age: "
age = gets.chomp
#block.call(nam,ag)
yield name, age
yield age
name
end
my_name = get_name("enter your name") do |name, age|
puts "That's a cool name, #{name}, #{age}"
end
my_name2 = get_name("enter your age") do |age|
puts "That's a cool age, #{age}"
end
puts "my_name: #{my_name} #{my_name2}"
我的输出:
treehouse:~/workspace$ ruby calling_blocks.rb
enter your name: ahmed
age: 25
That's a cool name, ahmed, 25
That's a cool name, 25,
enter your age: 25
age: 25
That's a cool age, 25
That's a cool age, 25
my_name: ahmed 25
该代码的问题在于,在跟踪它时,我发现输出无关紧要,这是我认为一定会发生的情况:
1- 第一个 get_name 块发送一个带有问题 "enter your name" 的提示,然后方法 get_name 首先打印短语 "enter your name" 作为参数调用提示, 然后该方法将名称作为输入并将年龄作为输入
2- 第一个 yield "yield name,age" 将名字和年龄发送回第一个 get_name 区块,通过 |name, age| 在区块中收到。 , 然后它们都显示在
puts "That's a cool name, #{name}, #{age}"
这样
That's a cool name, ahmed, 25
3- 第二个 yield "yield age" 这次只发送回第一个 get_name 区块年龄,它是通过 |name, age| 在区块中接收到的,这次我们发送了回到 block 只有一个参数,而 block 有两个参数,这次 block 上的 name 参数收到了来自 "yield name" 的 age 参数,而 block 上的 age 参数什么也没收到,所以在 block 中, #{name} 只显示值,而 #{age} 什么都不显示
puts "That's a cool name, #{name}, #{age}"
这样
That's a cool name, 25,
我的追踪是真的吗?
因为如果它是真的,为什么在第二个 get_name 块中,即
my_name2 = get_name("enter your age") do |age|
puts "That's a cool age, #{age}"
end
输出是:
That's a cool age, 25
That's a cool age, 25
而不是:
That's a cool age, ahmed
That's a cool age, 25
另一个问题:
在
puts "my_name: #{my_name} #{my_name2}"
为什么#{my_name2}的值=25,不是=ahmed,知道get_name方法的最后一行,我returns名字,不是年龄?
这个问题的简短版本:
请帮我追踪我的代码,告诉我到底发生了什么?
1) get_name
方法将 name
和 adge
生成块。在一个块中,这些变量被赋值:name="ahmed", age=25
。输出是 That's a cool name, ahmed, 25
2) get_name
方法产生 adge
块。在一个块中,这些变量被赋值:name=25, adge=nil
。 (这是一个 Proc,而不是 lambda,因此它将 nil
设置为未获取的变量)。输出为 That's a cool name, 25,
。看到 25
后面的逗号了吗?它实际上也打印 nil
,但是 nil.to_s
是空字符串。
3) my_name = "ahmed" - 变量被赋值
4) 由于您的新提示是 "enter your age" 而您输入的是 25,因此它被分配给 get_name
方法中的 name
变量。然后,您再次输入 25,该值也将分配给 age
。
5) get_name
产生两个值(name
和 age
现在是 25
和 25
)只取第一个的块.然后 get_name
为该块产生一个值 age
。
6) my_name_2=get_name#name=25
您只能使用显式参数形式 (&block
) 或 yield
,但不能同时使用两者。现在你的 &block
参数完全被忽略了。
如果您使用 &block
,您可以将 yield(
替换为 block.call(
。
无论哪种情况,调用堆栈都不是特别复杂。在您调用 yield(
或 block.call(
的位置,它进入给定块(您调用 puts
的位置),然后转到下一行。
另一个需要理解的重要事情是块不验证传递给它们的参数数量。有人在 Whosebug 评论中给出了一条建议(不知道来源 link),我觉得这些建议有助于记住。块的行为类似于 proc——它们不验证参数的数量,你可以记住这一点,因为这些词很相似。方法的行为类似于 lamdas——它们确实验证了 args 的数量。
因此,当您连续两次调用 yield
时,就是使用不同的参数多次调用 同一块 。当您使用不同的 do
部分调用该函数两次时,您提供了 两个不同的块。
这是我根据有关 TeamTreeHouse ruby 轨道上的 Ruby 块的视频课程创建的代码,这是代码及其输出..
我的代码:
def get_name(prompt, &block)
print prompt + ": "
name = gets.chomp
print "age: "
age = gets.chomp
#block.call(nam,ag)
yield name, age
yield age
name
end
my_name = get_name("enter your name") do |name, age|
puts "That's a cool name, #{name}, #{age}"
end
my_name2 = get_name("enter your age") do |age|
puts "That's a cool age, #{age}"
end
puts "my_name: #{my_name} #{my_name2}"
我的输出:
treehouse:~/workspace$ ruby calling_blocks.rb
enter your name: ahmed
age: 25
That's a cool name, ahmed, 25
That's a cool name, 25,
enter your age: 25
age: 25
That's a cool age, 25
That's a cool age, 25
my_name: ahmed 25
该代码的问题在于,在跟踪它时,我发现输出无关紧要,这是我认为一定会发生的情况:
1- 第一个 get_name 块发送一个带有问题 "enter your name" 的提示,然后方法 get_name 首先打印短语 "enter your name" 作为参数调用提示, 然后该方法将名称作为输入并将年龄作为输入
2- 第一个 yield "yield name,age" 将名字和年龄发送回第一个 get_name 区块,通过 |name, age| 在区块中收到。 , 然后它们都显示在
puts "That's a cool name, #{name}, #{age}"
这样
That's a cool name, ahmed, 25
3- 第二个 yield "yield age" 这次只发送回第一个 get_name 区块年龄,它是通过 |name, age| 在区块中接收到的,这次我们发送了回到 block 只有一个参数,而 block 有两个参数,这次 block 上的 name 参数收到了来自 "yield name" 的 age 参数,而 block 上的 age 参数什么也没收到,所以在 block 中, #{name} 只显示值,而 #{age} 什么都不显示
puts "That's a cool name, #{name}, #{age}"
这样
That's a cool name, 25,
我的追踪是真的吗? 因为如果它是真的,为什么在第二个 get_name 块中,即
my_name2 = get_name("enter your age") do |age|
puts "That's a cool age, #{age}"
end
输出是:
That's a cool age, 25
That's a cool age, 25
而不是:
That's a cool age, ahmed
That's a cool age, 25
另一个问题: 在
puts "my_name: #{my_name} #{my_name2}"
为什么#{my_name2}的值=25,不是=ahmed,知道get_name方法的最后一行,我returns名字,不是年龄?
这个问题的简短版本: 请帮我追踪我的代码,告诉我到底发生了什么?
1) get_name
方法将 name
和 adge
生成块。在一个块中,这些变量被赋值:name="ahmed", age=25
。输出是 That's a cool name, ahmed, 25
2) get_name
方法产生 adge
块。在一个块中,这些变量被赋值:name=25, adge=nil
。 (这是一个 Proc,而不是 lambda,因此它将 nil
设置为未获取的变量)。输出为 That's a cool name, 25,
。看到 25
后面的逗号了吗?它实际上也打印 nil
,但是 nil.to_s
是空字符串。
3) my_name = "ahmed" - 变量被赋值
4) 由于您的新提示是 "enter your age" 而您输入的是 25,因此它被分配给 get_name
方法中的 name
变量。然后,您再次输入 25,该值也将分配给 age
。
5) get_name
产生两个值(name
和 age
现在是 25
和 25
)只取第一个的块.然后 get_name
为该块产生一个值 age
。
6) my_name_2=get_name#name=25
您只能使用显式参数形式 (&block
) 或 yield
,但不能同时使用两者。现在你的 &block
参数完全被忽略了。
如果您使用 &block
,您可以将 yield(
替换为 block.call(
。
无论哪种情况,调用堆栈都不是特别复杂。在您调用 yield(
或 block.call(
的位置,它进入给定块(您调用 puts
的位置),然后转到下一行。
另一个需要理解的重要事情是块不验证传递给它们的参数数量。有人在 Whosebug 评论中给出了一条建议(不知道来源 link),我觉得这些建议有助于记住。块的行为类似于 proc——它们不验证参数的数量,你可以记住这一点,因为这些词很相似。方法的行为类似于 lamdas——它们确实验证了 args 的数量。
因此,当您连续两次调用 yield
时,就是使用不同的参数多次调用 同一块 。当您使用不同的 do
部分调用该函数两次时,您提供了 两个不同的块。