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

时间:2013-05-26 04:46:54

标签: ruby global-variables

我通过“学习编程”来学习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。我可以将这两个数组推送到另一个数组并返回,但这似乎并没有简化任何事情。

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

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

3 个答案:

答案 0 :(得分:3)

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

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

作为您如何组织课程/方法的概述:

class Deck
  def shuffle
  end

  def draw_hand
  end
end

class Hand
end

class Card
end

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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