我使用什么策略来避免ruby中的全局变量?



我正在通过Chris Pine的'Learn to Program'学习Ruby。我试图应付没有全局变量。我有一个看起来很邋遢的命令提示21点程序(还不能分割)。我的前三个方法说明了我遇到的问题。在Pascal中,我会使用全局变量,并使用方法来操作这些全局变量。它看起来像这样(使用ruby伪语言)

$deck_of_cards = []
$player_hand   = []
$dealer_hand   = []
def create_deck
    $deck_of_cards = #numbers 1-52
end
def shuffle_deck
    $deck_of_cards = #shuffled up deck of cards
end
def opening_deal
    2.times do
        $player_hand.push $deck_of_cards.pop
        $dealer_hand.push $deck_of_cards.pop
    end
end
create_deck
shuffle_deck
opening_deal
我最终会得到一张洗牌牌,一张玩家手牌和一张发牌手牌。去掉全局变量,前两个方法现在看起来像这样:
def create_deck deck_of_cards
    deck_of_cards = #numbers 1-52
    return deck_of_cards
end
def shuffle_deck deck_of_cards
    deck_of_cards = #shuffled up deck of cards
    return deck_of_cards
end
deck = create_deck([])
deck = shuffle_deck(deck)

感觉有点奇怪,但我可以习惯它。

但我完全卡住了最后一个方法,这需要返回两个变量,player_hand和dealer_hand。我可以把这两个数组放到另一个数组中,然后返回,但这看起来并没有简化任何东西。

是否有一个通用的策略来处理这种情况,或者每种情况都有自己独特的解决方案?

我想到的另一种情况是一个国际象棋程序。既然象棋程序中的几乎所有方法都需要使用它的值,为什么将棋盘作为全局变量没有意义呢?

简短的回答:对象。面向对象编程允许封装数据,这样数据就不会污染全局命名空间。随着项目规模的扩大,将所有数据放在全局名称空间中变得不可维护。对象允许您将数据和方法分组为有意义的单元,然后可以更容易地重用和维护。

以你提供的例子为例,我们可以制作deck和hand对象。这允许我们轻松地创建多个deck和hand,因为这些对象封装和管理它们的数据。

作为如何组织类/方法的粗略大纲:

class Deck
  def shuffle
  end
  def draw_hand
  end
end
class Hand
end
class Card
end

一般来说,使用面向对象编程技术,您将定义类并创建这些类的对象,然后传递这些对象。你可以把对象想象成数组,因为它们可以包含很多相关的数据,但比数组更好的是,数据元素可以有名字,可以是任何类型,而不需要是相同的类型,它们带有命名函数来操作数据。(实际上,在Ruby中,数组元素可以是任何类型,不需要是相同的类型,Hash元素也是如此,而且Hash元素有名称,但Ruby在这方面很特殊。)

保持简单,你可以像这样继续你的程序:

def opening_deal deck_of_cards
    player_hand = []
    dealer_hand = []
    2.times do
        player_hand.push deck_of_cards.pop
        dealer_hand.push deck_of_cards.pop
    end
    return player_hand, dealer_hand
end
player_hand, dealer_hand = opening_deal deck

使用全局变量是一个坏习惯,但是使用全局常量并不是坏事,或者换句话说,在主名称空间中定义常量。当需要全局变量时,您总是可以在主名称空间中定义常量。可变对象,如字符串,散列,数组可以修改,即使它是一个常量。如果这还不够,你需要更复杂的东西,那么你可以定义一个模块(这是常量的特殊情况),并在该模块上定义方法来访问你想做的事情,并使用实例变量将复杂的信息封装在该模块中。

相关内容

  • 没有找到相关文章

最新更新