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

我正在通过Chris Pine的“学习编程”来学习Ruby。 我试图在没有全局变量的情况下应对。 我有一个草率的命令提示二十一点程序(不能拆分)我的前三个方法说明了我遇到的问题。 在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。 我可以将这两个数组推送到另一个数组并返回,但这似乎并没有简化任何事情。

是否有处理此问题的一般策略,或者每种情况都有自己独特的解决方案吗?

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

简短的回答:对象。 面向对象编程允许您封装数据,以便它不会污染全局命名空间。 随着项目变得越来越大,将所有数据都放在全局命名空间中变得不可维护。 对象允许您将数据和方法分组为有意义的单元,然后可以更轻松地重复使用和维护。

因此,例如,通过您提供的示例,我们可以制作甲板和手形物体。 这使我们可以轻松创建多个卡座和手,因为这些对象封装和管理其数据。

作为如何组织类/方法的概述:

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

通常,使用面向对象的编程技术,您可以定义类并创建这些类的对象,然后传递这些对象。 您可以将对象视为类似于数组,因为它们可以包含大量相关数据,但比数组更好,因为数据元素可以具有名称,可以是任何类型,并且不需要是相同的类型,它们随附用于操作数据的命名函数。 (实际上,在Ruby中,Array元素可以是任何类型,并且不需要是相同的类型,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 

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