Standardize the API
Closed this issue · 5 comments
All attributes parser are modules and the association parser is an class.
To create custom parsers is more easy to do this with a class instead a module, see:
module CompetenceParser
include I18n::Alchemy::DateParser
extend self
def localize(value)
if value
I18n.localize value, :format => :competence
else
value
end
end
protected
def i18n_format
I18n.t(:competence, :scope => [:date, :formats])
end
end
With a class we can do this:
class CompetenceParser < I18n::Alchemy::DateParser
def localize(value)
if value
I18n.localize value, :format => :competence
else
value
end
end
protected
def i18n_format
I18n.t(:competence, :scope => [:date, :formats])
end
end
Or we can do more:
class CompetenceParser < I18n::Alchemy::DateParser
def localize(value)
if value
I18n.localize value, :format => :competence
else
super
end
end
protected
def i18n_format
I18n.t(:competence, :scope => [:date, :formats]) || super
end
end
And with a class, we can raise exceptions without some methods like localize or parser.
raise "You must implement localize" unless parser.respond_to?(:localize)
What do you think?
I agree that it seems easier to implement a custom parser just by inheriting from a class rather than including a module, but at the end, there's no real gain. You don't need to use extend self
if you don't want, for instance, or you don't even need to include/inherit from I18n::Alchemy
.
super
and raise
can be implemented as is, by including a module you can call super
, so for this case I think there's no real advantage on one or another approach.
A bit of history: parsers are implemented as modules because they don't actually need to save any state, they're just a bunch of related methods grouped by a module. So initially, there was no need to do DateParser.new.parse
if you didn't need to... DateParser.parse
was enough. On the other hand, AssociationParser
was added later specifically to parse
a hash of attributes from associations (if the association was localized), before assigning these attributes. There's no concept of localize
in AssociationParser
. It'd even be better to call it Association
only I think.
That said, I feel a bit unsure to change the parsers from modules to classes. Do you have anything else in mind to do with a class instead?
Also, if we go with a class model, do you think we should instantiate them only once for that particular localized object, on every parse/localize call, or only once for the entire application (singleton)?
Thanks mate! :)
Singleton is a good approach!
I thinking in a class because I not "saw" an standard API to build my own custom parsers, as I said, I thinking in an standard API to that anyone can easily build own API :)
The API should be an object that responds to both localize
and parse
. Whether it's a class or a module or something else, should't really matter :). The case is when someone is using a default parser and extending it.
But yeah, I agree we can have something that shows the common approach to do that, thanks!
@carlosantoniodasilva can be closed due to a lack of activity.
README already have the instructions for custom parsers.
TY!