Renum 1.1: pretty instance-specific method definition
You could always define instance-specific behavior on Renum values the same way you can on any object in Ruby:
enum :FakeWord do
Foo()
Bar()
Baz()
"no extra stuff here"
end
end
"here's the foo stuff"
end
That works fine, but it's a little ugly.
Starting this afternoon (with release 1.1) you can do this instead:
enum :FakeWord do
Foo do
"here's the foo stuff"
end
end
Bar()
Baz()
"no extra stuff here"
end
end
FakeWord::Foo
will have its own implementation of extra_stuff
while FakeWord::Bar
and FakeWord::Baz
will have the one defined inside the enum
block. This was implemented by just instance_eval
'ing the given block against the instance just after creating it. A def
form in an instance_eval
'd block ends up defining a singleton method, so it's equivalent to the uglier version above.
This ends up looking almost exactly like the Java enum equivalent for defining constant-specific class bodies.
Since the block is instance_eval
'd, if you prefered you could do any initialization there instead of defining an init
method. Depending on what you've got going on it may turn out to be more readable. Here's a contrived example from the spec translated to that style.
# init-with-args-style
enum :Size do
Small("Really really tiny")
Medium("Sort of in the middle")
Large("Quite big")
attr_reader :description
@description = description
end
end
# instance-block-per-value-style
enum :Size do
Small {@description = "Really really tiny" }
Medium {@description = "Sort of in the middle" }
Large {@description = "Quite big" }
attr_reader :description
end
The latter is probably slightly easier to digest, but it's also an extremely simple case, so I'd expect your mileage to vary quite a bit. (Note that you can do both an init
with arguments AND an associated block. Renum evals the block before calling init
, so any instance-specific behavior is in place before your init runs.)
Anyway, comment, suggest, complain, fork, improve, and enjoy.
2 comments:
Hello!
I am using your Renum plugin and I have a question.
At every rails request, I'm seeing this warning for each enum I created: gems/renum-1.3.1/lib/renum/enumerated_value_type_factory.rb:13: warning: already initialized constant Marital_Statuses
I'm kind of new to ror, but it seems odd that the enum is being recreated every request.
I have put a debug line in the init method inside a enum and it's being called a lot times.
What can I do to stop these warnings?
FYI, My enums are in the folder models/enums and each enum file is enum.rb and enum :enumName do ... end
Thanks a lot!
Marcos
Sorry for the slow response.
Is this only happening in the development Rails environment?
Are you loading or requiring the file that defines your constants, or just relying on Rails to auto-load the file when you reference your constants?
Post a Comment