Comments (5)
- Well, the
method_missing
allows us to checkTwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES
for every call toto_*_s
(eg..to_medium_s
,to_long_s
, etc). It's also flexible in case another type of date format is ever introduced. I understand what you mean about knowing the (finite) list of methods that can be called inDateTimeTokenizer
, but I don't think it would necessarily be cleaner or more efficient to add separate methods. I'm in favor of addingrespond_to?
and the appropriate call tosuper
. - Yes! I've wanted to do this for a long time but I never knew quite how to approach it without an extra level of polymorphism. I'm glad you brought up the idea of Delegators, I didn't know a design pattern already existed in Ruby for this. From what I understand, this would be the definition for
LocalizedObject
with a delegator:
module TwitterCldr
class LocalizedObject < SimpleDelegator
attr_reader :locale, :base_obj, :formatter
def __getobj__
@base_obj
end
# ... existing implementation
end
end
- I think I initially wanted
options
to be passed tosetup_for
and then to the call tofmt_class.new
, but there's no need to do that because all the additional formatting capabilities are handled into_s
, not when the formatter is created. You're absolutely right thatsetup_for
changes the object and could have unexpected consequences. I'd be in favor of getting rid of it and having theto_*
functions return new instances ofLocalizedNumber
, that's a great idea. - Absolutely, these should be throwing
NotImplementedError
. Good catch.
from twitter-cldr-rb.
I added NotImplementedError
usage in #28 and I'll get to 2 and 3 later. Regarding method_missing
the problem is that it's too powerful tool that makes it pretty easy to shoot yourself in the foot. So it's better to avoid it when possible. And I think the implementation without method_missing
might be simple in this case.
Here is how it might look with call to super
and implemented respond_to?
:
def method_missing(method, *args, &block)
type = extract_format_type(method)
if type
@formatter.format(@base_obj, :type => type.to_sym)
else
super
end
end
def respond_to?(method_name)
extract_format_type(method_name) ? true : super
end
def extract_format_type(method_name)
format_type = method_name.to_s[/to_(\w+)_s/, 1]
format_type if format_type && TwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES.include?(format_type.to_sym)
end
And here is a solution with dynamic methods definition:
TwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES.each do |format_type|
define_method "to_#{format_type}_s" do
@formatter.format(@base_obj, :type => format_type.to_sym)
end
end
As a bonus we get full-fledged methods that are visible in the list of LocalizedDataTime
instance methods:
1.9.3-p125 :001 > TwitterCldr::LocalizedDateTime.instance_methods(false).sort
#=> [:formatter_const, :to_date, :to_default_s, :to_full_s, :to_long_s, :to_medium_s, :to_s, :to_short_s, :to_time]
from twitter-cldr-rb.
@KL-7 alright you've convinced me! Using define_method
is definitely cleaner and more readable, plus I like that it gives us actual methods. Let's do it. Metaprogramming FTW!
from twitter-cldr-rb.
Hi @camertron, I submitted PR #29 with all the changes discussed here except delegation to the wrapped object in LocalizedObject
. The reason is that I have some doubts about that. I though it might be a good idea so we can do smth like:
Time.now.localize.strftime('%H') #=> "21"
or even
10.localize + 2 #=> 12
While I still think that the first use case might be handy sometimes, the second is quite confusing. Methods like that (arithmetic operations on numbers, strings concatenations, time manipulations) usually return an instance of the same class: you add 2
to Fixnum
object 10
and get 12
as a Fixnum
in return. To follow these expectations 10.localize + 2
should also return an object of the same type as the original object - in this case of type LocalizedNumber
. But as we think about simple delegation the result of 10.localize + 2
(that is LocalizedNumber
+ Fixnum
) will be Fixnum
and not a LocalizedObject
. As the result our localization methods won't be available on the result object.
To eliminate this kind of confusion it might be better to leave things as they are and expect that users will call methods like localize
at the very last moment when they've already used all the functionality of the original class (e.g., completed all arithmetic operations with a Fixnum
object). What do you think?
from twitter-cldr-rb.
As per our discussion over Skype today, I agree with you that delegation probably isn't the right answer here. Initially I thought it would be really cool if we could expose the base object's methods. However, I think we should still expose certain methods like strftime
for LocalizedDateTime
that do standard formatting. We can convert tokens like %H
into their CLDR equivalents, run the string through the DateTimeTokenizer
, and format the result for the user.
from twitter-cldr-rb.
Related Issues (20)
- CLDR 35 Dev Branch HOT 2
- Formatting a full datetime with a time zone gives current time timezone (PST instead of PDT) HOT 4
- Incorrect list formatter behaviour HOT 2
- Exception when using hyphenate HOT 1
- Incorrect LikelySubtags.locale_for behaviour HOT 1
- Incorrect ListFormatter behaviour HOT 6
- Weekday names `:wide` format is the same as `:abbreviated` HOT 5
- Ruby 3.1.0 with Psych 4 forces YAML.safe_load and throws Psych::DisallowedClass HOT 1
- Month names :narrow format returns array of digits rather than the first letter of each month HOT 3
- Ruby 2.7+ compatibility issue/question HOT 1
- Warning when running Sorbet HOT 2
- Why use :one instead of :name HOT 1
- Remove lone release HOT 1
- Missing titlecase and/or uppercase mappings? HOT 1
- Add support for yMMMMd (October 7, 2022) HOT 2
- `format: :long` breaks when combined with currency formatting HOT 4
- Breaking by word a string containing Japanese and Latin characters HOT 3
- Contributor access revoked HOT 1
- Wrong language name is returned for Norwegian Nynorsk (nn) HOT 1
- 2fa391f25c21837ccf5b0af82a66a21d5b5926aa HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from twitter-cldr-rb.