Ruby - 哈希属性的Setter方法 [英] Ruby - Setter methods for hash properties
问题描述
现在我有一个角色的统计信息保存在一个散列表中,我希望能够通过公共方法进行设置。我得到了这样的工作:
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 $ c $的迭代器c>哈希似乎很笨重,但我还没有找到更好的方法来完成任务。
[] =
方法。这可以这样做: 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屋!