Controlling attribute setting in a Struct

R

rbysamppi

I'm using a bunch of Struct classes in a program; they're a perfect
way for me to bundle and access attributes. But in one of my
subclasses of Struct, I'm trying to control setting attributes so that
setting an attribute above a certain value causes an effect, like
this:

# All attributes are integers.
MyMaximumBoundedStruct <
Struct.new:)life, :strength, :charisma, :weapon)
@maximum = 1000

def what_happens_when_an_attribute_is_set(attribute_name, new_value)
if new_value <= @maximum
super(attribute, new_value)
else
raise ArgumentError, "#{attribute_name} set above maximum"
end
end

end

rabbit_stats = MyMaximumBoundedStruct.new
rabbit_stats.life = 128 # okay, normal behavior
rabbit_stats.life = 1001 # raises an exception

Is there some method I can override to get this sort of behavior? Or
is this impossible or impractical using Structs (which would make me
sad, because they're otherwise perfect for me)?

Thank you all in advance.
 
R

Raul Parolari

unknown said:
I'm using a bunch of Struct classes in a program; they're a perfect
way for me to bundle and access attributes. But in one of my
subclasses of Struct, I'm trying to control setting attributes so that
setting an attribute above a certain value causes an effect
...

You just need to redefine the setter attribute; we can automate the
production of the setter attributes as follows (I assume that the
maximum has the same value for all attributes, else this would need to
be modified a bit):


class MyMaxBoundedStruct < Struct.new:)life, :strength, :charisma,
:weapon)

# class variable (depending on Spec, a Constant could be used)
@@maximum = 1000

arr = %w[life strength charisma weapon]

arr.each do |m|
define_method("#{m}=") do |val|
if val < @@maximum
super(val)
else
raise ArgumentError, "#{m} set above maximum"
end
end
end

end

rabbit = MyMaxBoundedStruct.new

rabbit.life = 999
rabbit.weapon = 10
p rabbit.life # => 999

rabbit.life = 1000 # => ArgumentError: life set above maximum
 
R

Raul Parolari

Uups, I treated the maximum as the "first invalid value"; correction:

class MyMaxBoundedStruct < Struct.new:)life, :strength, :charisma,
:weapon)

# class variable (depending on Spec, a Constant could be used)
@@maximum = 1000

arr = %w[life strength charisma weapon]

arr.each do |m|
define_method("#{m}=") do |val|
if val <= @@maximum
super(val)
else
raise ArgumentError, "#{m} set above maximum"
end
end
end
end # class

rabbit = MyMaxBoundedStruct.new

rabbit.strength = 1000 # ok
rabbit.strength = 1001 # Argument: strength set above maximum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top