【问题标题】:Ruby Simple Program Tracing (Yield - Method)Ruby 简单程序跟踪(Yield - 方法)
【发布时间】:2018-09-17 13:15:05
【问题描述】:

这是我基于 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 块发送一个带有问题“输入您的姓名”的提示,然后方法 get_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上的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方法的最后一行,我返回的是name,而不是age?

这个问题的简短版本: 请帮我追踪我的代码,告诉我到底发生了什么?

【问题讨论】:

    标签: ruby-on-rails ruby methods yield trace


    【解决方案1】:

    您只能使用显式参数形式 (&block) 或 yield,但不能同时使用两者。现在你的 &block 参数被完全忽略了。

    如果您使用&block,则可以将yield( 替换为block.call(

    在任何一种情况下,调用堆栈都不是很复杂。在你调用yield(block.call( 的地方,它进入给定的块(你调用puts)然后进入下一行。

    要理解的另一件重要事情是,块不会验证传递给它们的参数的数量。有人在 StackOverflow 评论(不知道源链接)中给出了一条建议,我觉得这很有帮助。块的行为类似于 procs - 它们不验证参数的数量,您可以记住这一点,因为单词相似。方法的行为类似于 lamdas - 它们确实验证了 args 的数量。

    因此,当您连续两次调用yield 时,即使用不同的参数多次调用相同的块。当您使用不同的do 部分调用该函数两次时,您提供了两个不同的块

    【讨论】:

      【解决方案2】:

      1) get_name 方法将 nameadge 生成块。在块内分配了这些变量: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) 由于您的新提示是“输入您的年龄”并且您输入的是 25,因此它被分配给 get_name 方法中的 name 变量。然后,您再次输入 25,该值也将分配给 age

      5) get_name 产生两个值(nameage 现在是 2525)这个块只接受第一个。然后get_name 为该块生成一个值age

      6)my_name_2=get_name#name=25

      【讨论】:

      • 感谢您的帮助,我真的明白了,我在跟踪中的错误在哪里 :) ,想增加一个重击,但我需要至少 15 个代表才能重击某人
      • 很高兴为您提供帮助
      猜你喜欢
      • 2014-01-27
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多