GithubHelp home page GithubHelp logo

RFC about twitter-cldr-rb HOT 5 CLOSED

twitter avatar twitter commented on August 14, 2024
RFC

from twitter-cldr-rb.

Comments (5)

camertron avatar camertron commented on August 14, 2024
  1. Well, the method_missing allows us to check TwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES for every call to to_*_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 in DateTimeTokenizer, but I don't think it would necessarily be cleaner or more efficient to add separate methods. I'm in favor of adding respond_to? and the appropriate call to super.
  2. 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
  1. I think I initially wanted options to be passed to setup_for and then to the call to fmt_class.new, but there's no need to do that because all the additional formatting capabilities are handled in to_s, not when the formatter is created. You're absolutely right that setup_for changes the object and could have unexpected consequences. I'd be in favor of getting rid of it and having the to_* functions return new instances of LocalizedNumber, that's a great idea.
  2. Absolutely, these should be throwing NotImplementedError. Good catch.

from twitter-cldr-rb.

KL-7 avatar KL-7 commented on August 14, 2024

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.

camertron avatar camertron commented on August 14, 2024

@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.

KL-7 avatar KL-7 commented on August 14, 2024

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.

camertron avatar camertron commented on August 14, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.