动态变量值

时间:2012-02-20 22:36:10

标签: ruby dynamic

我正在寻找有关动态变量的一些建议。特别是如果我正在充分利用instance_variable_set或者是否有更好的方式我应该关注。提前感谢任何建议。现在是代码。

我正在创造一个二十一点游戏。我有两个value_creator方法,如下所示:

class Blackjack

  def dealers_card_value_creator
    @card_value = @hit_dealer
      case
      when @card_value.match(/\d+/)
        @card_value = @card_value.match(/\d+/)[0].to_i
      when @card_value.match(/Ace/)
        if @dealers_hand >= 11
          @card_value = 1
        else
          @card_value = 11
        end
      when @card_value.match(/Jack|Queen|King/)
        @card_value = 10
      else
        puts "there was an error. please try again."
      end
    @hit_dealer = @card_value
    @dealers_hand = @dealers_hand + @hit_dealer
      if @dealers_hand > 21 then puts "Dealer went over 21. You won $#{@bet}. Nice!" 
        deal end
  end

def players_card_value_creator
    @card_value = @hit_player
    case
    when @card_value.match(/\d+/)
      @card_value = @card_value.match(/\d+/)[0].to_i
    when @card_value.match(/Ace/)
      if @players_hand >= 11
        @card_value = 1
      else
        @card_value = 11
      end
    when @card_value.match(/Jack|Queen|King/)
      @card_value = 10
    else
      puts "there was an error. please try again."
    end
    @hit_player = @card_value
    @players_hand = @players_hand + @hit_player
      if @players_hand > 21 then puts "You went over 21. You lost $#{@bet}. Try again." 
        deal end
  end
end

如你所见,它们基本相同。所以我创建了这个方法供经销商和玩家使用。

def value_creator(string)
    hit = "@#{string}" #returns either @player or @dealer
    instance_variable_set(hit, "#{@hit_card}")
    @card_value = hit
    case
    when @card_value.match(/\d+/)
      @card_value = @card_value.match(/\d+/)[0].to_i
    when @card_value.match(/Ace/)
      if "@#{string}"_hand >= 11
        @card_value = 1
      else
        @card_value = 11
      end
    when @card_value.match(/Jack/)
      @card_value = 10
    when @card_value.match(/Queen/)
      @card_value = 10
    when @card_value.match(/King/)
      @card_value = 10
    else
      puts "there was an error. please try again."
    end
    "@#{string}" = @card_value
    "@#{string}"_hand = "@#{string}"_hand + "@#{string}"
  end

  def hit_dealer
    @hit_card = @shuffled_deck.pop
    value_creator("dealer")
  end

  def hit_player
    @hit_card = @shuffled_deck.pop
    value_creator("player")
  end

但是当我尝试使用"@#{string}"调用hit_player的值时,它会返回@player,而不是它所分配的值。

很多代码,但我希望有助于更好地理解我正在尝试做的事情,并将有助于更好的直接建议。再次,先谢谢。

1 个答案:

答案 0 :(得分:1)

中的评论
hit = "@#{string}" #returns either @player or @dealer

不正确。 结果不是@player@dealer,而是字符串'@player''@dealer'

您可以执行以下操作:

def value_creator( variant )
  case variant 
    when :player
      hit = @player
    when :dealer
      hit = @dealer
    else
      raise ArgumentError
    end
    #....
end
def hit_dealer
  @hit_card = @shuffled_deck.pop
  value_creator(:dealer)
end

def hit_player
  @hit_card = @shuffled_deck.pop
  value_creator(:player)
end

替代方法:使用instance_variable_get获取值。

  hit = instance_variable_get("@#{string}")

另外两种可能性:

  hit = eval("@#{string}")

(我不喜欢它 - eval是邪恶的)。

使用send

您必须先定义两个访问者:

attr_reader :player
attr_reader :dealer

然后你可以使用:

def value_creator( string )
  hit = send( string )