Passing a variable to lock in Ruby implicitly

I would like to rewrite this snippet:

Chips.fix_game(324565) do |game_id|
  player1.chips.gain(game_id, 200) # chips qty
  player2.chips.lose(game_id, 200)
end

      

thus:

Chips.fix_game(324565) do
  player1.chips.gain(200)
  player2.chips.lose(200)
end

      

passing game_id

to player1.chips

the API entry point.

The second snippet is more concise and there is no room for change game_id

inside the block.

How would you implicitly pass a value game_id

from a method Chips.fix_game

to an object player1.chips

?

+3


source to share


1 answer


Chips

can provide current_game_id

, which is installed with fix_game

, for example:

class Chips
  @@current_game_id = nil

  def self.current_game_id
    @@current_game_id
  end

  def self.fix_game(game_id)
    previous_game_id = current_game_id
    @@current_game_id = game_id
    yield
  ensure
    @@current_game_id = previous_game_id
  end
end

class Player
  def gain(amount)
    puts "gaining #{amount} chips in game #{Chips.current_game_id}"
  end
end

player = Player.new

Chips.fix_game(1) do
  player.gain(100)
end
#=> "gaining 100 chips in game 1"

Chips.fix_game(2) do
  player.gain(200)
end
#=> "gaining 200 chips in game 2"

      

Restoring the previous game ID after yield

allows you to block blocks:



Chips.current_game_id     #=> nil
Chips.fix_game(1) do
  Chips.current_game_id   #=> 1
  Chips.fix_game(2) do
    Chips.current_game_id #=> 2
  end
  Chips.current_game_id   #=> 1
end
Chips.current_game_id     #=> nil

      

While this looks convenient, global state can lead to difficult tasks to debug. Be careful.

0


source







All Articles