Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中创建动态函数_Ruby - Fatal编程技术网

在Ruby中创建动态函数

在Ruby中创建动态函数,ruby,Ruby,我正在为一副牌创建一个模块。我希望Deck对象能够接受我在下面编写的shuffle方法的另一个实现 我最初的想法是,我的shuffle方法应该接受一个参数,该参数是响应shuffle的任何对象。这是一个好方法吗 我不确定如何在Ruby中实现这一点 module PlayingCards class Deck RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace'] SUITS = %w{ Clubs Diamonds Hearts Sp

我正在为一副牌创建一个模块。我希望Deck对象能够接受我在下面编写的shuffle方法的另一个实现

我最初的想法是,我的shuffle方法应该接受一个参数,该参数是响应shuffle的任何对象。这是一个好方法吗

我不确定如何在Ruby中实现这一点

module PlayingCards
  class Deck
    RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
    SUITS = %w{ Clubs Diamonds Hearts Spades }

    attr_accessor :cards, :discarded
    def initialize(options={})
      @cards = []
      @discarded = []
      options[:number_decks] ||= 1

      options[:number_decks].times do
        (RANKS).product(SUITS).each do |rank, suit|
          @cards << Card.new(rank, suit)
        end
      end
    end

    def shuffle()
      cards.push(*discarded).shuffle!
      discarded = []
      self
    end
  end
end
我希望Deck对象能够接受我在下面编写的shuffle方法的另一个实现

有几种方法可以实现这一点。没有唯一正确的答案。以下是一些技巧:

  • 只需定义多个方法:

    def shuffle
      cards.push(*discarded).shuffle!
      discarded = []
      self
    end
    
    # For example
    def shuffle_before_replacing
      cards.shuffle!
      cards.push(*discarded)
      discarded = []
      self
    end
    
  • 定义高阶方法,例如:

    SHUFFLE_MODES = {
      standard: ->(cards, discarded) { cards.push(*discarded).shuffle },
      # ...
    }
    
    def shuffle(mode: :standard)
      cards = SHUFFLE_MODES.fetch(mode).call(cards, discarded)
      discarded = []
      self
    end
    
    def shuffle(shuffler: Shuffler::Standard)
      shuffler = shuffler.new(cards, discarded)
      shuffler.shuffle
      cards = shuffler.cards
      shuffler = shuffler.discarded
      self
    end
    
    # ...
    
    module Shuffler
      class Base
        attr_reader :cards, :discarded
        def initialize(cards, discarded)
          @cards = cards
          @discarded = discarded
        end
      end
    end
    
    module Shuffler
      class Standard < Base
        def shuffle
          @cards.push(*discarded).shuffle
          @discarded = []
          self
        end
      end
    end
    
    module Shuffler
      class BeforeReplacing < Base
        def shuffle
          @cards.shuffle!
          @cards.push(*discarded)
          @discarded = []
          self
        end
      end
    end
    
  • 注入依赖项以执行洗牌,例如:

    SHUFFLE_MODES = {
      standard: ->(cards, discarded) { cards.push(*discarded).shuffle },
      # ...
    }
    
    def shuffle(mode: :standard)
      cards = SHUFFLE_MODES.fetch(mode).call(cards, discarded)
      discarded = []
      self
    end
    
    def shuffle(shuffler: Shuffler::Standard)
      shuffler = shuffler.new(cards, discarded)
      shuffler.shuffle
      cards = shuffler.cards
      shuffler = shuffler.discarded
      self
    end
    
    # ...
    
    module Shuffler
      class Base
        attr_reader :cards, :discarded
        def initialize(cards, discarded)
          @cards = cards
          @discarded = discarded
        end
      end
    end
    
    module Shuffler
      class Standard < Base
        def shuffle
          @cards.push(*discarded).shuffle
          @discarded = []
          self
        end
      end
    end
    
    module Shuffler
      class BeforeReplacing < Base
        def shuffle
          @cards.shuffle!
          @cards.push(*discarded)
          @discarded = []
          self
        end
      end
    end
    
    def shuffle(shuffler:shuffler::Standard)
    洗牌者=洗牌者。新(牌,丢弃)
    洗牌
    纸牌
    洗牌者=洗牌者
    自己
    结束
    # ...
    模块洗牌器
    阶级基础
    属性读卡器:卡,已丢弃
    def初始化(卡,已丢弃)
    @卡片
    @丢弃的
    结束
    结束
    结束
    模块洗牌器
    等级标准<基准
    def洗牌
    @扑克牌。推(*丢弃)。洗牌
    @丢弃=[]
    自己
    结束
    结束
    结束
    模块洗牌器
    替换前的类
    结束

  • 第三种方法的一个主要好处是,您可以独立于
    Deck
    类定义
    Shuffler
    s,因此,例如,您最终可能会有多种类型的
    Deck
    ,每种类型都可以以不同的方式使用
    Shuffler
    接口。(例如,您可能需要洗牌不同的东西,或者洗牌多次。)

    同样,您也可以独立于
    测试
    洗牌器。这是双向的;您现在还可以独立于
    Shuffler
    测试
    (通过将模拟对象传递到
    组#shuffle
    方法)

    这种技术是三种技术中最先进的,我通常只希望有经验的开发人员在更复杂的场景中充分利用这种技术。鉴于我掌握的信息有限,很难说在您的案例中,这样的抽象是否还需要付出努力



    上面的所有代码都未经测试,因此可能不会被当场发现,但希望这能给您一些启发。

    我想您需要将
    卡作为
    洗牌
    中的最后一行来返回值。别介意,我错过了
    我有点搞不清楚您使用
    丢弃的
    变量的目标是什么。我最好的猜测是,每次你洗牌时,有可能会丢弃一些牌;但是,在重新洗牌之前,牌组应该始终完全恢复到其原始状态?而且,我发现
    shuffle
    方法应该返回
    discarded
    列表,这有点不恰当。我认为这样的方法返回<代码>自我<代码>更为正常。我更新了我的问题,包括我手上的另一个类。可以折叠一只手,将牌推入丢弃的阵列中,该阵列存在于牌组对象上。。。当一副牌洗牌时,它需要知道留在牌堆中的牌和折叠的牌。这真的很有帮助,汤姆,我从中得到了一些有用的信息。谢谢。哦。。是的,修好了,谢谢。如果你发现了这样一个愚蠢的错误,请随意编辑我的帖子!