Ruby - 哈希属性的Setter方法 [英] Ruby - Setter methods for hash properties

查看:104
本文介绍了Ruby - 哈希属性的Setter方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



现在我有一个角色的统计信息保存在一个散列表中,我希望能够通过公共方法进行设置。我得到了这样的工作:

  class字符
attr_reader:str,:con,:dex,:wis,: int,:level,:mods,:stats
def初始化str,con,dex,wis,int,cha,level = 1
@stats = {:str => str,:con => con,:dex => dex,:wis => wis,:int => int,:cha => cha}
@mods = {}
@level = level

@ stats.each_pair do | key,value |
@mods [key] =((value / 2)-5).floor
end
end
$ b def [] =(index,value)
@stats [index] = value
end
end

我实例化一个新字符,然后通过运行 newChar.stats [:str] = 12 更新 @stats 但是,我似乎也可以使用这种方法修改 @mods ,这是不可取的。 newChar.mods [:str] = 15 会成功修改 @mods



稍微分开一点,我用来创建我的 @mods 哈希似乎很笨重,但我还没有找到更好的方法来完成任务。

你甚至没有打电话给你的 [] = 方法。这可以这样做:

  newChar [:str] = 123 

而不是

  newChar.stats [:str] = 123 

如此调用 newChar.stats [:str] = 123 你甚至不需要你的方法定义。原因是 newChar.stats 以及 newChar.mods 都会返回实际的哈希,然后可以修改。

一个可能的解决方法是冻结 @mods 变量,使其不能再被修改:

  def初始化str,con,dex,wis,int,cha,level = 1 
#省略...

@ stats.each_pair do | key,value |
@mods [key] =((value / 2)-5).floor
end

@ mods.freeze
end

如果您不希望能够更改 @mods 再次。尝试设置一个值会导致错误:

  newChar.mods [:con] = 123 
#RuntimeError :无法修改冻结哈希值

但是,您可以在类中覆盖<$ c $总的来说,完整的类将是:



pre> 类字符
attr_reader:str,:con,:dex,:wis,:int,:level,:mods,:stats
def初始化str,con ,dex,wis,int,cha,level = 1
@stats = {:str => str,:con => con,:dex => dex,:wis => wis,:int => int,:cha => cha}
@mods = {}
@level = level

@ stats.each_pair do | key,value |
@mods [key] =((value / 2)-5).floor
end

@ mods.freeze
end
end


I've been tooling around with Ruby by converting a pen and paper RPG to a script.

Right now I have a character's stats kept in a hash, which I would like to be able to set via public method. I got that working with:

class Character
    attr_reader :str, :con, :dex, :wis, :int, :level, :mods, :stats
    def initialize str, con, dex, wis, int, cha, level = 1
        @stats = { :str => str, :con => con, :dex => dex, :wis => wis, :int => int, :cha => cha }
        @mods = {}
        @level = level

        @stats.each_pair do |key, value|
            @mods[key] = ((value / 2 ) -5).floor
        end
    end

    def []=(index, value)
        @stats[index] = value
    end
end

This allows me to instantiate a new character, then update @stats by running newChar.stats[:str] = 12

However, I also seem to be able to modify the @mods using this method as well, which is undesirable. newChar.mods[:str] = 15 will successfully alter the @mods hash, which from my understanding should not be possible with the current setter method.

On a slightly separate note, the iterator I'm using to create my @mods hash seems clunky but I haven't found anything better to accomplish the task.

解决方案

You did not even call your []= method in your example. This would be done like so:

newChar[:str] = 123

instead of

newChar.stats[:str] = 123

so to call newChar.stats[:str] = 123 you do not even need you method definition. The reason is that newChar.stats as well as newChar.mods will both return the actual hash which can then be altered.

One possible workaround is to freeze the @mods variable so it can't be altered any more:

def initialize str, con, dex, wis, int, cha, level = 1
    # omitted ...

    @stats.each_pair do |key, value|
        @mods[key] = ((value / 2 ) -5).floor
    end

    @mods.freeze
end

This is a good solution if you never want to be able to change @mods again. Trying to set a value will result in an error:

newChar.mods[:con] = 123
# RuntimeError: can't modify frozen Hash

Inside your class, you can, however, overwrite @mods entirely.

To summarize, the full class would be:

class Character
    attr_reader :str, :con, :dex, :wis, :int, :level, :mods, :stats
    def initialize str, con, dex, wis, int, cha, level = 1
        @stats = { :str => str, :con => con, :dex => dex, :wis => wis, :int => int, :cha => cha }
        @mods = {}
        @level = level

        @stats.each_pair do |key, value|
            @mods[key] = ((value / 2 ) -5).floor
        end

        @mods.freeze
    end
end

这篇关于Ruby - 哈希属性的Setter方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆