Search code examples
rubyinstance-variables

Create Ruby instance variable to default based off of other instance variable values


I am creating a Ruby class that takes a hash as an argument:

class Player
include PlayerHelper
attr_accessor :at_bats, :hits, :walks, :hbp, :sac_flies, :singles, :doubles,
              :triples, :hr, :put_outs, :assists, :errors, :er, :ip, :so,
              :stolen_bases, :caught_stealing
def initialize(hash)
  @at_bats = hash.fetch(:at_bats, nil)
  @hits = hash.fetch(:hits, nil)
  @walks = hash.fetch(:walks, nil)
  @hbp = hash.fetch(:hbp, nil)
  @sac_flies = hash.fetch(:sac_flies, nil)
  @singles = hash.fetch(:singles, nil)
  @doubles = hash.fetch(:doubles, nil)
  @triples = hash.fetch(:triples, nil)
  @hr = hash.fetch(:hr, nil)
  @put_outs = hash.fetch(:put_outs, nil)
  @assists = hash.fetch(:assists, nil)
  @errors = hash.fetch(:errors, nil)
  @er = hash.fetch(:er, nil)
  @ip = hash.fetch(:ip, nil)
  @walks = hash.fetch(:walks, nil)
  @hits = hash.fetch(:hits, nil)
  @so = hash.fetch(:so, nil)
  @stolen_bases = hash.fetch(:stolen_bases, nil)
  @caught_stealing = hash.fetch(:caught_stealing, nil)
end

I want to give the user the option of including :singles and first check if :singles was included in the hash. If so, give it the hash's value. This part I have working.

What I can't get to work is to give @singles the value of :hits - (:doubles + :triples + :hr) if the :singles key doesn't exist. I have tried making a separate method to call initially, but this doesn't seem to work.

How can I set the value of @singles based off of the other hash values if there was no :singles key included?


Solution

  • That's what the second argument of the fetch method can be used for:

    def initialize(hash)
      # ...
      @hits = hash.fetch(:hits, nil)
      @doubles = hash.fetch(:doubles, nil)
      @triples = hash.fetch(:triples, nil)
      @hr = hash.fetch(:hr, nil)
      @singles = hash.fetch(:singles, @hits - (@doubles + @tripples + @hr))
      # ...
    end
    

    However, note that since you are defaulting all values to nil, you could hit undefined method on nil:NilClass-type errors if those values are not passed into the constructor! You may wish to set some different defaults, or make them required arguments...