Использование хэшей в качестве переменных экземпляра - PullRequest
0 голосов
/ 25 октября 2019

Я очень новичок в Ruby.

При использовании хэшей в качестве переменных экземпляра это

class Hero
  def initialize (stats={})

Или

class Hero
  def initialize (stats={'Atk':0, 'Def':0})

Или

class Hero
  def initialize (stats)

Или как-то лучше? Я получаю около 30 ошибок в строке инициализации из-за неожиданного ':' и т. Д.

Вероятно, в строке инициализации имеется 10 хэшей. Лучше вместо этого иметь индивидуальную переменную для каждого состояния? Заранее спасибо!

Извините, если это дубликат, но я не видел никаких вопросов по этому поводу.

Мой класс:

class Hero

  attr_accessor :nam, :desc, :race, :clas, :bg, :heroLVL, :hitpoints, :armC, :spd, :sdcwic, :modifiers, :proficiencies, :skills, :languages, :inventory, :equipment, :coins, :features, :feats, :spellsKnown, :spellSlots, :maxSpellSlots, :currentSpellSlots, :cantrips

  def initialize(nam, desc = {}, race, clas = [], bg, heroLVL = {}, hitpoints = {'Current HP' : 0, 'Max HP' : 0, 'Temp HP' : 0}, armC, spd, sdcwic = {'Stre' : 0, 'Dex' : 0, 'Con' : 0, 'Wis' : 0, 'Int' : 0, 'Cha' : 0}, modifiers = {'Stre' : 0, 'Dex' : 0, 'Con' : 0, 'Wis' : 0, 'Int' : 0, 'Cha' : 0, 'Proficiency' : 0}, proficiencies = [], skills = {}, languages = [], inventory = {}, equipment = {}, coins = {'Copper' : 0, 'Silver' : 0, 'Electrum' : 0, 'Gold' : 0, 'Platinum' : 0}, features = [], feats = [], spellsKnown = [], spellSlots = {}, maxSpellSlots = {}, currentSpellSlots = {}, cantrips = [])
    #description
    @nam = nam
    @desc = desc
    #stats
    @race = race
    @clas = clas 
    @bg = bg
    @heroLVL = heroLVL
    @hitpoints = hitpoints
    @armC = armC
    @spd = spd
    #modifiers
    @sdcwic = sdcwic
    @modifiers = modifiers
    @proficiencies = proficiencies
    @skills = skills
    @languages = languages
    #inventory
    @inventory = inventory
    @equipment = equipment
    @coins = coins
    #features
    @features = features
    @feats = feats
    #casting
    @spellsKnown = spellsKnown
    @spellSlots = spellSlots
    @maxSpellSlots = maxSpellSlots
    @currentSpellSlots = currentSpellSlots
    @cantrips = cantrips
  end
end

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

Я думаю, вы должны упростить это для себя и сделать что-то вроде:

class Hero 

  def initialize(stats={})
    stats.each do |k,v|
      class_eval { attr_accessor k }
      send("#{k}=",v)
    end
  end

end

Обратите внимание, что зацикливание stats экономит вам около 450 символов. И ваш код намного чище.

Вы бы назвали Hero что-то вроде:

Hero.new name: 'billy', 
         race: 'elf',
         desc: {},
         clas: []

Обратите внимание, что все находится в форме key: value. И каждый key превращается в метод на экземпляре Hero, который будет возвращать value, который был передан.

Итак, если вы сделаете:

@hero = Hero.new name: 'billy', 
                 race: 'elf',
                 desc: {},
                 clas: []

Тогда вы сможете сделать:

@hero.name
 -> billy

Это не удастся, кстати, если вы попытаетесь позвонить @hero.spellsKnown, потому что (в этом примере) нет пары key: value с keyspellsKnown. Итак, вы можете вернуться к использованию attr_accessor, что-то вроде:

class Hero 

  attr_accessor *%w(
    name desc race clas bg heroLVL hitpoints armC spd sdcwic modifiers 
    proficiencies skills languages inventory equipment coins features 
    feats spellsKnown spellSlots maxSpellSlots currentSpellSlots cantrips
  ).freeze

  def initialize(stats={})
    stats.each do |k,v|
      send("#{k}=",v)
    end
  end

end

Теперь все будет хорошо, если вы позвоните spellsKnown.

Кроме того, кстати, вы можете взглянуть на Руководство по стилю Ruby . Такие имена, как spellsKnown и hitpoints не являются обычными рубинами. Они должны быть больше похожи на spells_known и hit_points, соответственно.

И, я знаю, это может показаться болезненным, но я предлагаю вам разобраться полностью. nam должно быть name. Позже вам не придется пытаться вспомнить, какие усечения вы использовали.

0 голосов
/ 25 октября 2019

Это

class Hero
  def initialize (stats)
    @stats = stats
  end

Предполагается, что статистика похожа на хэш, {name: "Generic Hero name, hp: 400, ...}. Кроме того, в Ruby есть нечто, называемое" аргументами по ключевым словам ". Так что есливы передаете имя: «Герой», hp: 400 и т. д. в метод, все автоматически преобразуется в один хеш.

РЕДАКТИРОВАТЬ: не передавайте его в качестве аргумента, просто установите еговнутри самого класса. Если вы на самом деле не передаете какую-либо статистику и просто хотите пустое состояние, нет смысла передавать его. Если вы передаете значения, а не просто пустые массивы / хэши, вы должны передать всю переменную statsзатем просто назначьте, используя @name = stats [name].

def initialize
  @desc = {}
  @class = []
  ...
end

И т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...