Ruby if elsif else 问题

时间:2021-02-10 08:38:41

标签: ruby

大家早上好

第一次发帖,希望有人能帮帮我。

我正在尝试在 Ruby 中创建一段执行以下操作的代码:

"greeting_hello(str) 接受传递的name参数返回"Hello Lori!",如果name参数等于"Lori",则返回"Hello John!"如果name参数等于"John"或"你好!”如果 name 参数等于任何其他参数。”

def greeting_hello(str)
    
    str = ("")
    
    if str == "Lori"
        puts "Hello Lori!"
    elsif str == "John"
        puts "Hello John!"
    else
        puts "Hello!"
    end
    
    return str 
end

我在使用上述代码时得到的输出是:

Hello Lori!
Lori #why is this displaying?

Hello John!
John #same here, why is this displaying?

Hello! #this displays as intended if Lori or John is not input.

感谢任何帮助或指点,谢谢。

6 个答案:

答案 0 :(得分:0)

您正在 str 函数内重新分配 greetings_hello 变量。

你取函数参数 str 然后给它分配一个空字符串 然后检查空字符串是否等于 Lori (此处失败) 然后你检查空字符串是否等于 John (它也失败了比较) 正因为如此,它会打印出 Hello!。 之后,您在函数末尾返回 str。因为 str"",所以它只返回空字符串。

您想要的是不重新分配函数参数。

答案 1 :(得分:0)

这是你想做的吗? 即:分配参数的默认值并使用 case :

def greeting_hello(str = "")

    case str
    when "Lori"
        "Hello Lori"
    when "John"
            "hello John"
    else
        "hello"
    end
end

答案 2 :(得分:0)

你应该试试下面的代码!!!

def greeting_hello(str)
    ["Lori", "John"].include?(str) ? "Hello #{str}!" : "Hello!"
end

我在这里使用了 ruby​​ 三元运算符和数组包含方法。

请参阅以下三个链接了解更多详情

Ternary operator

Array include

String interpolation

答案 3 :(得分:0)

它返回您传入的名称,因为您在方法末尾返回 str 。所以它会遍历你的 if/else 条件和 puts 你想要的字符串,但是你在最后返回字符串。

答案 4 :(得分:0)

REPL 中的返回值

Ruby 在标准输出上打印的内容与其作为方法或表达式的值返回的内容之间存在差异。这就是您意外文本的来源。

当您在 irb、pry 或任何其他 REPL 中运行代码时,每个 Ruby 表达式都会向控制台返回一个值。如果您以非交互方式运行代码(例如 ruby foo.rb),您将不会看到额外的输出。

在这种特定情况下,它返回 str 的值,因为您的方法以 return str 结尾,因此您明确返回该值。这只是有点不明显,因为您的 REPL 没有很好地设计它。我建议将以下内容添加到您的 ~/.irbrc 中,以使返回值在视觉上更加直观:

IRB.conf[:PROMPT][:DEFAULT][:RETURN].prepend '#'

当您在方法定义的顶部将其设置为 "" 时,您还破坏了传入 str 的值,因此您发布的代码实际上不可能是 < em>返回除 "" 之外的任何内容,无论它在标准输出上打印什么。即使没有显式返回,Kernel#puts 也始终返回 nil,这也不太可能是您期望看到的返回值。

重构代码

Kernel#puts 替换为 Kernel#p 将达到您的预期:

# str is assigned nil if a name isn't passed as an argument
def greeting_hello(str=nil)
    if str == "Lori"
        p "Hello Lori!"
    elsif str == "John"
        p "Hello John!"
    else
        p "Hello!"
    end
end

greeting_hello 'Lori'
"Hello Lori!"
#=> "Hello Lori!"

greeting_hello 'John'
"Hello John!"
#=> "Hello John!"

greeting_hello 'Abby'
"Hello!"
#=> "Hello!"

greeting_hello
"Hello!"
#=> "Hello!"

如果你只想有一个合理的返回值,你可以到此为止。

更高级的重构

使用一些 Ruby 3.0.0 语义的更高级的重构并且不会尝试拒绝除 LoriJohn 以外的名称,可能如下所示:

# use interpolation to increase flexibility, with a conditional space added
# after the word "Hello" if str is neither nil nor an empty string
def greeting_hello str=nil
  optional_space = ' ' unless str.nil? or str.empty?
  sprintf 'Hello%s%s!', optional_space, str
end

# test against various inputs
['Lori', 'John', 'Fred', '', nil].map { greeting_hello _1 }
#=> ["Hello Lori!", "Hello John!", "Hello Fred!", "Hello!", "Hello!"]

这可能比解决当前问题所需要做的更多,但知道在 Ruby 中做事情的方法总是不止一种通常会很有帮助。其中一些可能非常紧凑,尽管有时需要在巧妙的代码和可读的代码之间取得平衡。您在这方面的表现可能会有所不同。

答案 5 :(得分:0)

删除返回字符串

删除 str = “”

这解决了我的问题。

感谢支持。