【问题标题】:How to return value from a Ruby function for use in the rest of the program如何从 Ruby 函数返回值以用于程序的其余部分
【发布时间】:2014-12-02 11:00:03
【问题描述】:

我编写了一个小的 ruby​​ 函数,它可以根据字符串变量的长度来改变它。打印输出显示,在函数中,变量被改变了——但是当它稍后在程序中被调用时,它总是被重置为默认值。

#ruby variable test

def mrn_value(mrn_length, mrn)
if mrn_length < 7 
  case mrn_length
   when 6
       mrn = '0' << mrn
        return mrn
   when 5
       mrn = '00' + mrn
        return mrn 
   when 4
       mrn = '000' + mrn
       return mrn 
   when 3
    puts mrn
       mrn = '0000' + mrn
       puts mrn
      return mrn 
   when 2
    mrn = mrn.to_s
    puts 'mrn of 2 length'                             #prints 'mrn of 2 length'
       mrn = '00000' + mrn
       puts 'mrn altered in case statement: ' + mrn    #prints 'mrn altered in case statement 0000012'
  when 1
       mrn = '000000' + mrn
        return mrn 
   end
     end 
   end

mrn = 12
mrn = mrn.to_s
mrn_length = mrn.length



mrn_value(mrn_length, mrn)
puts 'Returned MRN: ' + mrn                             #prints '12'

我需要的是让返回的 MRN 成为更改后的 MRN。想法?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    我建议您详细了解为什么 Ruby 是“按值传递”。在mrn = 12 中,mrn 是一个变量,一个指向对象的指针,在这种情况下是 12。

    当您将mrn 传递给mrn_value 时,您传递的是该指针的副本。现在你有 2 个指针指向同一个对象。当您执行mrn = '00000' + mrn 时,您是在告诉第二个指针不再指向 2,而是指向右侧的其他任何内容。如您所见,mrn_value 方法之外的原始 mrn 指针仍指向 2。

    您可以在Posts on StackOverflow on why Ruby is 'pass by value' 上阅读更多内容。给你一个简化的版本来演示:

    a = 1
    
    def will_a_be_changed(a)
      a = 2
      puts a #=> 2
    end
    
    will_a_be_changed(a)
    puts a #=> 1
    

    【讨论】:

    • 感谢您的解释和示例。我认为“return”命令会导致更改后的变量在函数之外可用,我弄错了吗?
    • Ruby 是按值传递,而不是按引用传递。你不能传递变量,变量不是对象。你只能传递对象。
    • @Elisa - 如果您遵循以下 rohit89 的示例,这将起作用。您必须将其重新分配给 mrn。
    • @Phil 哦,我明白了。我习惯于在 PHP 中执行此操作,在这里我会“返回”一个值以供使用并已经分配它。
    【解决方案2】:

    在所有行中,例如:

    mrn = '0' << mrn
    

    你没有做你正在做的事情。您在此处创建一个新字符串并将其分配给一个局部变量。这个局部变量指向了一个已经传递给这个方法的字符串对象,在这个赋值之后它指向了另一个对象,这个对象在方法执行后就丢失了。

    相反,您需要替换此变量指向的对象:

    mrn.replace('0' + mrn)
    

    mrn.prepend('0')
    

    请注意,这只是可能的,因为字符串是可变的,这不适用于 Fixnums 或 Symbols。

    既然解释了这一点,为什么不简单地使用现有的字符串方法,例如rjust

    mrn = '12'
    mrn = mrn.rjust(7, '0')
    

    【讨论】:

    • 感谢您的建议——我尝试使用 mrn.rjust,但由于某种原因,在该格式中它不会写入我正在存储结果的 .csv。它确实以其他格式保存它们。 耸耸肩
    【解决方案3】:

    这个问题是由 ruby​​ 通过值而不是通过引用传递方法参数引起的 (ish)。

    如果您将mrn 更改为@mrn,它将起作用。 @ 使它成为一个实例变量,我猜在这种情况下它使它在整个模块中可用。

    【讨论】:

      【解决方案4】:

      如果我正确理解您的要求,您可以这样做:

      #ruby variable test
      
      def mrn_value(mrn_length, mrn)
        value = ""
        if mrn_length < 7 
          case mrn_length
          when 6
            value = '0' << mrn
          when 5
            value = '00' + mrn
          when 4
            value = '000' + mrn
          when 3
            puts mrn
            value = '0000' + mrn
            puts mrn
          when 2
            value = mrn.to_s
            puts 'mrn of 2 length'                             #prints 'mrn of 2 length'
            value = '00000' + mrn
            puts 'mrn altered in case statement: ' + mrn    #prints 'mrn altered in case statement 0000012'
          when 1
            value = '000000' + mrn
          end
        end
        value
      end
      
      mrn = 12
      mrn = mrn.to_s
      mrn_length = mrn.length
      
      
      
      mrn = mrn_value(mrn_length, mrn)
      puts 'Returned MRN: ' + mrn 
      

      【讨论】:

        【解决方案5】:

        重新分配值有什么问题?

        mrn = mrn_value(mrn_length, mrn)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-13
          • 1970-01-01
          • 2019-04-14
          • 1970-01-01
          • 2014-01-21
          • 1970-01-01
          • 2016-03-20
          • 1970-01-01
          相关资源
          最近更新 更多