如何在模块内添加类

问题描述

因此,我在Ruby中制作了一个非常简单的命令行应用程序-该应用程序从JSON文件加载产品数据,向用户显示产品,用户可以将其添加到他们的购物车中,购物车应用折扣并显示总数。

我将“产品”和“购物车”包含在模块中,并且设法对产品进行了重构,因此它们也属于一类(这使得测试等操作更加容易)。

但是,我无法确定如何成功将购物车更改为Cart模块中的Class Cart。 我不想每次添加产品时都创建一个新的购物车。.只想添加到数组中

欢迎任何反馈和指导:)

文件(5)


  1. 商店
require_relative './app/controller'

shop = Controller.new
shop.run
  1. 控制器
require_relative './cart'
require_relative './product'
require_relative './menu'

class Controller
  def initialize
    @menu = Menu.new
  end

  def run
    loop do
      @menu.display_menu
    end
  end
end
  1. 菜单
require 'tty-prompt'
require_relative './product.rb'
require_relative './cart.rb'

class Menu
  puts "Hi,welcome to Bob's Bits the #1 CLI Shop"
  def display_menu
    puts "--------------------------------------------------------------"
    prompt = TTY::Prompt.new
    menu_selection = prompt.select("Select a menu item",["View All Products","View Shopping Cart","Exit"])
  
    case menu_selection
    when "View All Products"
      Products::view_all_products
    when "View Shopping Cart"
      Cart::view_shopping_cart
    when "Exit"
      puts "Goodbye"
      exit
    end
  end
end
  1. 产品
require 'json'

module Products
  class Product 
    attr_accessor :uuid,:name,:price
    def initialize(uuid,name,price) 
      @uuid = uuid
      @name = name
      @price = price
    end
  end

  def self.view_all_products
    # # Open & load products file (parse and read)
    file = File.open "./products.json"
    product_data = JSON.load file
  
    product_list = product_data.each do | product |
      Product.new(product["uuid"],product["name"],product["price"])
    end
  
    # Print out each items name for the menu selection
    options = []
    product_list.each do | item |
      details = item["name"] + " $" + ('%.2f' % item["price"]).to_s
      options.push(details)
    end

    # List product names so that user can select
    prompt = TTY::Prompt.new
    puts `clear`
    item_to_add_to_cart = prompt.select("Select which items to add to cart",options)
    
    # Match the name selected with product 
    product_for_cart = product_list.select do |product |
      item_to_add_to_cart.include?(product["name"])
    end
    Cart::add_to_cart(product_for_cart)
  end
end
  1. 购物车
require 'tty-prompt'

module Cart
  @shopping_cart = []

  # Add the product selected to the shopping cart array
  def self.add_to_cart(product_for_cart)
    @shopping_cart.push(product_for_cart).flatten!
    puts `clear`
  end

  def self.view_shopping_cart
    # apply promo discounts based on cart subtotal
    def self.discount_calc
      # calculator subtotal of items in cart
      subtotal = @shopping_cart.map {|item| item["price"]}.sum
      @cart_data = {}
      # track the discount for display & calc later on
      if subtotal >= 100.0 
        @cart_data[:discount] = 20
      elsif subtotal >= 50
        @cart_data[:discount] = 15
      elsif subtotal >= 20.0
        @cart_data[:discount] = 10
      else
        @cart_data[:discount] = 0
      end
      @cart_data[:total] = (subtotal - (subtotal * @cart_data[:discount] / 100.00))
      @cart_data[:savings] = subtotal - @cart_data[:total]
      return @cart_data
    end
    # run the discount calculator
    discount_calc
    # Output cart to the user
    puts ""
    puts "Products in Shopping Cart:"
    @shopping_cart.each_with_index do | item,i |
      puts "  #{i + 1}. #{item["name"]} - $#{'%.2f' % item["price"]}\n\n"
    end
    puts "discount applied: #{@cart_data[:discount]}% (Total Savings $#{'%.2f' % @cart_data[:savings]}!)\n\n"
    puts "Total After discount: $#{'%.2f' % @cart_data[:total]}\n\n"
  end
end

解决方法

您可以将购物车作为参数传递给构造函数和方法

class Cart
  def initialize
    @shopping_cart = []
  end

  # ...
end

module Products
  # ...

  def self.view_all_products(cart)
    # ...
    cart.add_to_cart(product_for_cart)
  end
end

class Menu
  puts "Hi,welcome to Bob's Bits the #1 CLI Shop"

  def initialize(cart)
    @cart = cart
  end

  def display_menu
    puts "--------------------------------------------------------------"
    prompt = TTY::Prompt.new
    menu_selection = prompt.select("Select a menu item",["View All Products","View Shopping Cart","Exit"])
  
    case menu_selection
    when "View All Products"
      Products::view_all_products(@cart)
    when "View Shopping Cart"
      @cart.view_shopping_cart
    when "Exit"
      puts "Goodbye"
      exit
    end
  end
end

class Controller
  def initialize
    @cart = Cart.new
    @menu = Menu.new(@cart)
  end

  def run
    loop do
      @menu.display_menu
    end
  end
end

shop = Controller.new
shop.run