我通过“学习编程”来学习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。我可以将这两个数组推送到另一个数组并返回,但这似乎并没有简化任何事情。
是否有处理此问题的一般策略,或者每种情况都有自己独特的解决方案?
另一种想到的情况是国际象棋程序。为什么让棋盘成为全局变量是没有意义的,因为国际象棋程序中的几乎所有方法都需要使用它的价值?
答案 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)
拥有全局变量是一个坏习惯,但是拥有全局常量,或者换句话说,在主名称空间中定义的常量也不错。当需要全局变量时,您始终可以在主名称空间中定义常量。可变对象(如字符串,散列,数组)即使是常量也可以修改。如果这还不够,你需要更复杂的东西,那么你可以定义一个模块(这是常量的一个特例),并在该模块上定义方法以访问你想要做的事情,并封装复杂的信息在该模块中使用实例变量。