有没有办法可以从 ruby​​ 中的另一个类调用方法?

时间:2021-01-09 17:18:36

标签: ruby

呼叫我的 print_statement 时是否可以看到更新的余额?在我的 Transaction 类中,我使用 @amount@timestamp 实例变量将事务存储到我的 @transaction 类中的 Account 实例变量中。然后我调用我的 print_statement 方法,该方法只打印出每笔交易的 @timestamp@amount

在我想要的结果中,我还需要打印出每笔交易的更新 Balance。我是编码新手,所以任何建议将不胜感激!

我想要的结果:

date || credit || debit || balance
14/01/2012 || || 500.00 || 2500.00
13/01/2012 || 2000.00 || || 3000.00
10/01/2012 || 1000.00 || || 1000.00

我目前的结果:

2.7.0 :001 > require './lib/account'
 => true 
2.7.0 :002 > require './lib/transaction'
 => false 
2.7.0 :003 > account = Account.new
2.7.0 :004 > account.deposit(100)
 => [#<Transaction:0x00007f9eff8941a8 @amount=100, @timestamp="09/01/2021">] 
2.7.0 :005 > account.withdraw(50)
 => [#<Transaction:0x00007f9eff8941a8 @amount=100, @timestamp="09/01/2021">, #<Transaction:0x00007f9efd9673c0 @amount=-50, @timestamp="09/01/2021">] 
2.7.0 :006 > account.balance
 => 50 
2.7.0 :007 > account.print_statement
   date   || credit || debit || balance || 
-------------------------------------------
09/01/2021||100||  || Balance ||
09/01/2021||  ||-50|| Balance ||
 => [nil, nil] 

帐号类

require_relative 'transaction'
 
 class Account

  attr_reader :transactions

  def initialize
    @transactions = []
  end

  def balance
    @transactions.map(&:amount).sum
  end

  def deposit(amount)
    @transactions << Transaction.new(amount)
  end

  def withdraw(amount)
    @transactions << Transaction.new(-amount)
  end

  def header
    puts '   date   || credit || debit || balance || '
    puts '-------------------------------------------'
  end

  def print_statement
    header
    @transactions.map(&:formate)
  end
end

事务类

class Transaction
  attr_reader :amount, :timestamp

  def initialize(amount)
    @amount = amount
    @timestamp = Time.now.strftime("%d/%m/%Y")
  end


  def formate
    if @amount > 0
      puts "#{@timestamp}||#{@amount}||  || Balance ||"
    elsif
      puts "#{@timestamp}||  ||#{@amount}|| Balance ||"
    end
  end
end

3 个答案:

答案 0 :(得分:1)

当然,在另一个类中调用特定类的方法的方法不止一种,最简单和最短的方法(因为您提到您是新编码,所以我只会向您展示两种避免混淆的方法):

>

假设您在 Account 类中,在一个方法中,您可以创建 Transaction 对象的实例并调用任何函数(为简单起见,在公共范围内):

t = Transaction.new(...)
t.formate

这和你写的时候做的差不多:

@transactions.map(&:formate)

基本上,上面说的对于该列表中的每个事务实例调用方法format

实现此目的的另一种简单方法是将方法定义为类方法(例如其他语言中的 static 函数,例如 C#),例如:

class A
  def self.print_foo
     p 'Foo'
  end
end

根据上面的定义,您可以执行类似 A.print_foo 的操作。

还有其他方法可以实现这一点,但我认为这两个是基础。

注意:如果您在不同的文件中并使用 Plane Ruby(没有自动文件加载器,您可能需要导入/要求文件,但网站上已经有答案?)

希望以上内容有助于澄清! ?

答案 1 :(得分:1)

解决方案可能不止一种。

我给你举个简单的例子。 但首先让我祝贺你,我喜欢你到目前为止的编码方式,非常干净并且专注于每个类的公共方法,一个清晰而有意义的 API。

你缺少的是你需要什么样的数据结构来提出问题。

在我的解决方案中,我将使用 Struct,您可以使用 Hash,或者您可以在 Transaction 中构建一些方法来跟踪余额。 但我认为部分平衡是 Account 类的问题,所以这里有一个建议:

class Account

  attr_reader :transactions

  TransactionPartialBalance = Struct.new(:transaction, :balance_at_transaction)

  def initialize
    @transactions = []
    @transactions_with_balance = []
  end

  def balance
    @transactions.map(&:amount).sum
  end

  def deposit(amount)
    @transactions << Transaction.new(amount)
    @transactions_with_balance << TransactionPartialBalance.new(@transactions.last, balance)
  end

  def withdraw(amount)
    @transactions << Transaction.new(-amount)
    @transactions_with_balance << TransactionPartialBalance.new(@transactions.last, balance)
  end

  def header
    puts '   date   || credit || debit || balance || '
    puts '-------------------------------------------'
  end

  def print_transactions_balance
    p @transactions_with_balance
  end

  def print_statement
    header
    @transactions.map(&:formate)
  end
end

class Transaction
  attr_reader :amount, :timestamp

  def initialize(amount)
    @amount = amount
    @timestamp = Time.now.strftime("%d/%m/%Y")
  end


  def formate
    if @amount > 0
      puts "#{@timestamp}||#{@amount}||  || Balance ||"
    elsif
      puts "#{@timestamp}||  ||#{@amount}|| Balance ||"
    end
  end
end

if __FILE__ == $PROGRAM_NAME
  account = Account.new
  account.deposit(100)
  account.withdraw(50)
  account.balance
  account.print_transactions_balance
  # [#<struct Account::TransactionPartialBalance transaction=#<Transaction:0x0000562a986ecc38 @amount=100, @timestamp="10/01/2021">, balance_at_transaction=100>, 
  # #<struct Account::TransactionPartialBalance transaction=#<Transaction:0x0000562a986ecad0 @amount=-50, @timestamp="10/01/2021">, balance_at_transaction=50>]

end

答案 2 :(得分:1)

我认为您应该参考与每笔交易相关的帐户。然后,您可以使用该引用访问所需的帐户信息。由于您似乎也只有一个交易列表而不是存储固定余额,因此我认为您需要一种方法来在任何交易后获取余额。

首先,我向 Account 添加了一个 balance_after 方法来计算任何给定交易后的余额。它通过查找传入交易的索引,然后将传入交易之前的所有交易的金额相加来实现这一点。

require_relative 'transaction'
 
 class Account

  attr_reader :transactions

  def initialize
    @transactions = []
  end

  def balance
    @transactions.map(&:amount).sum
  end

  # new method to get the balance after a given transaction
  def balance_after(transaction)
    index = transactions.find_index(transaction)
    transactions[0..index].map(&:amount).sum
  end

  def deposit(amount)
    @transactions << Transaction.new(amount, self)
  end

  def withdraw(amount)
    @transactions << Transaction.new(-amount, self)
  end

  def header
    puts '   date   || credit || debit || balance || '
    puts '-------------------------------------------'
  end

  def print_statement
    header
    @transactions.map(&:formate)
  end
end

接下来,我将帐户信息添加到 Transaction 中,并在帐户引用上调用 balance_after() 方法,传递对当前事务的引用。

 class Transaction
  attr_reader :amount, :timestamp, :account

  def initialize(amount, account)
    @amount = amount
    @timestamp = Time.now.strftime("%d/%m/%Y")
    @account = account
  end

  def balance()
    @account.balance_after(self)
  end

  def formate
    if @amount > 0
      puts "#{@timestamp}||#{@amount}||  || #{balance} ||"
    elsif
      puts "#{@timestamp}||  ||#{@amount}|| #{balance} ||"
    end
  end
end