【问题标题】:Can I instantiate a class from a method within another class? (Ruby)我可以从另一个类中的方法实例化一个类吗? (红宝石)
【发布时间】:2020-05-11 09:51:59
【问题描述】:

我已经重做了这个问题并包含了两个文件的完整代码。在 touch_in 方法中,我试图在名为“journey”的变量中实例化一个 Journey 类。

require_relative 'journey'

class Oystercard

  MAXIMUM_BALANCE = 90

  MINIMUM_BALANCE = 1

  MINIMUM_CHARGE = 1

  def initialize
    @balance = 0
    @journeys = {}
  end

  def top_up(amount)
    fail 'Maximum balance of #{maximum_balance} exceeded' if amount + balance > MAXIMUM_BALANCE
    @balance += amount
  end

  def in_journey?
    @in_journey
  end

  def touch_out(station)
    deduct(MINIMUM_CHARGE)
    @exit_station = station
    @in_journey = false
    @journeys.merge!(entry_station => exit_station)
  end

  def touch_in(station)
    fail "Insufficient balance to touch in" if balance < MINIMUM_BALANCE
    journey = Journey.new
    @in_journey = true
    @entry_station = station
  end

  attr_reader :journeys

  attr_reader :balance

  attr_reader :entry_station

  attr_reader :exit_station

  private

  def deduct(amount)
    @balance -= amount
  end

end

Journey 文件如下:

    class Journey

  PENALTY_FARE = 6

  MINIMUM_CHARGE = 1

  def initialize(station = "No entry station")
    @previous_journeys = {}
  end

  def active?
    @active
  end

  def begin(station = "No entry station")
    @active = true
    @fare = PENALTY_FARE
    @entry_station = station
  end

  def finish(station = "No exit station")
    @active = false
    @fare = MINIMUM_CHARGE
    @exit_station = station
    @previous_journeys.merge!(entry_station => exit_station)
  end

attr_reader :fare

attr_reader :previous_journeys

attr_reader :entry_station

attr_reader :exit_station

end

我认为 'touch_in' 方法应该创建一个我调用方法的 'journey' 变量,例如 'finish(station)' 或 'active?'等等。当我尝试在 IRB 中执行此操作时,我收到以下错误:

2.6.3 :007 > journey
Traceback (most recent call last):
        4: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/bin/irb:23:in `<main>'
        3: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/bin/irb:23:in `load'
        2: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        1: from (irb):7
NameError (undefined local variable or method `journey' for main:Object)

我知道上面的大部分代码都写得很草率,除了“旅程”问题之外,可能还有其他部分不正确。如果是这种情况,请告诉我,我被告知的越多越好。

向在我第一次尝试时试图帮助我的任何人道歉,因为我说我仍然习惯 SO 并试图使帖子更易于阅读。

【问题讨论】:

  • 标题的意思是“我可以从另一个类中的方法实例化一个类吗”。
  • 是的,应该可以。不是吗?相反会发生什么?你有错误吗?出乎意料的结果?
  • @PaulM 您可以通过单击其下方的编辑链接来编辑您的问题。这次我编辑了你的标题。至于您的问题,请单击编辑并添加完全不起作用的内容。你有任何错误和回溯吗?有什么事情没有按预期工作(你期待什么,会发生什么)?
  • 你能添加什么不能按预期工作吗?预期行为是什么?实际行为与此有何不同?
  • @PaulM : 你不能require 两个文件相互。在执行Oystercard#touch_in 时,Ruby 一定已经看到了Journey 的定义。最简单的方法是require 包含Journey 定义的文件就在class Oystercard 之前。

标签: ruby class instantiation irb


【解决方案1】:
class Journey
    # ...
    def initialize
        puts "Journey initialized"
      # ...
    end
    # ...
  end


require_relative 'journey'

class Oystercard

    def initialize
    end
    # ...
    def touch_in(station)
      journey = Journey.new
      # ...
    end
  end

  Oystercard.new.touch_in("station")

stack_question$ ruby​​ oystercard.rb

旅程已初始化

它工作正常 - 您是否有超出问题范围的问题?

【讨论】:

  • 您好!我已经改写了问题,以提供有关我的问题的更多信息,感谢您的帮助!
  • @PaulM 从上面的 IRB sn-p 中,您将变量 'journey' 称为脱离上下文。此变量的范围(本地)为touch_in 方法。您不能在该方法的上下文之外调用该变量。如果你想这样做,你需要一个实例变量 - @journey = Journey.new
猜你喜欢
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 2015-01-23
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多