将 variables/parameters 从一个 Ruby class 传递给加载的 Ruby 程序

Passing variables/parameters from one Ruby class to a loaded Ruby program

下面的组合程序应该要求一个数字删除第一个数字(我们称这个新数字为 x),然后计算 x % 7。例如:(1121546 % 7) = 5

除了输入的数字将始终计算为 0 之外,这一切似乎都有效。modulo_7.rb 自行工作,并在传递参数时打印正确的结果。

问题是我没有正确传递变量/参数还是有其他问题?

class Number_check_interface
    def get_cert_number
        print "You are about to check receive the check number for a policy/cert id."
        @cert_id = nil
        until @cert_id.is_a?(Fixnum) do             
            puts " Enter the policy/cert ID. "  
            begin                               
                   @cert_id = Integer(gets)           
               rescue ArgumentError                
            end
        end         
    end
end

class Run_number_check_interface

    def run
        load 'modulo_7.rb'
        n = Number_check_interface.new                                 
        n.get_cert_number                                              

        checking_policy_number = Get_policy_check_digit.new(@cert_id)  
        checking_policy_number.create_check_digit
    end
end

run = Run_number_check_interface.new
run.run

modulo_7.rb

此程序删除 7 位数字的第一个数字(索引 0),returns 差值 7%18 是 4,因为 4 是 7 可以放入 18 的余数。

class Get_policy_check_digit
    def initialize(cert_id)
        #instance variable
        @cert = cert_id
    end

    def create_check_digit
        cert_id_6 = @cert.to_s
        cert_id_6.slice!(0)

        puts cert_id_6
        check_digit = cert_id_6.to_i % 7
        puts "Your check digit is #{check_digit}"
    end
end

# n = Get_policy_check_digit.new(1121546) When uncommented this will create a new instance
                                         # of Get_policy_check_digit with the parameter 1121546
# n.create_check_digit                    This will run the method create_check_digit with the
                                         # parameter 1121546

为什么这些是分开的 类?这里的设计看起来很奇怪,这是从其他语言移植过来的吗?它比它需要的更复杂。在不更改结构的情况下,这是错误的地方:

Run_number_check_interface 中,您正在阅读 @cert_id,它没有以该名称命名的实例变量,但 Number_check_interface 有。只是 return 它来自 get_cert_number:

class Number_check_interface
  def get_cert_number
    print "You are about to check receive the check number for a policy/cert id."
    cert_id = nil
    until cert_id.is_a?(Fixnum) do             
      puts " Enter the policy/cert ID. "  
      begin                               
        cert_id = Integer(gets)           
      rescue ArgumentError                
      end
    end
    cert_id     # <-- returing the value here
  end
end

class Run_number_check_interface
  def run
    load 'modulo_7.rb'
    n = Number_check_interface.new                                 
    cert_id = n.get_cert_number                                   # <-- saving here

    checking_policy_number = Get_policy_check_digit.new(cert_id)  # <-- no longer an ivar
    checking_policy_number.create_check_digit
  end
end

run = Run_number_check_interface.new
run.run

实例变量的范围是 class 的单个实例。因此,当您在 Number_check_interface 中说 @cert_id = Integer(gets) 时,您只是为 Number_check_interface 的特定实例设置了 @cert_id。然后,当你稍后在 Run_number_check_interface 中写 Get_policy_check_digit.new(@cert_id) 时,你指的是一个完全不同的 @cert_id,它特定于 Run_number_check_interface 的特定实例,而不是Number_check_interface 您之前存储在 n

简单的解决办法是从Number_check_interface#get_cert_number到return@cert_id,然后将returned值传给Get_policy_check_digit.new:

class Number_check_interface
    def get_cert_number
        print "You are about to check receive the check number for a policy/cert id."
        @cert_id = nil # This is an instance variable. It's only accessible
                       # from inside this instance of `Number_check_interface`
        until @cert_id.is_a?(Fixnum) do             
            puts " Enter the policy/cert ID. "  
            begin                               
                   @cert_id = Integer(gets)          
               rescue ArgumentError                
            end
        end
        return @cert_id # Return the contents of @cert_id
    end
end


class Run_number_check_interface

    def run
        load 'modulo_7.rb'
        n = Number_check_interface.new
        cert_number = n.get_cert_number # Here we call `get_cert_number` and
                                        # set `cert_number` to it's return
                                        # value.

        # Notice how we use `cert_number` here:
        checking_policy_number = Get_policy_check_digit.new(cert_number)
        checking_policy_number.create_check_digit
    end
end

其他提示:

  • Ruby 中的惯例是 name classes with CamelCase
  • 在文件顶部需要依赖项,而不是在方法调用的中间。
  • 除非你有很好的理由不这样做,否则请使用 require,而不是 load
  • 您可能需要更深入地思考这些 classes 的用途以及它们打算封装的行为。 API 现在对我来说似乎有点尴尬。记住,告诉,不要问。