How do I use hash keys as methods on a class?

后端 未结 5 1936
孤街浪徒
孤街浪徒 2020-12-05 05:16

I have a class and a hash. How can I get the members of the hash to dynamically become methods on the class with the key as the method name?

class User
  def         


        
5条回答
  •  借酒劲吻你
    2020-12-05 06:10

    Actually severin have a better idea, just because usage of method_missing is a bad practice, not all the time, but most of it.

    One problem with that code provided by severin: it returns value that have been passed to initializer, so you cannot change it. I suggest you a little different approach:

    class User < Hash
      def initialize(attrs)
        attrs.each do |k, v|
          self[k] = v
        end
      end
    
      def []=(k, v)
        unless respond_to?(k)
          self.class.send :define_method, k do
            self[k]
          end
        end
    
        super
      end
    end
    

    Lets check it:

    u = User.new(:name => 'John')
    p u.name
    u[:name] = 'Maria'
    p u.name
    

    And also you can do it with Struct:

    attrs = {:name => 'John', :age => 22, :position => 'developer'}
    keys = attrs.keys
    
    user = Struct.new(*keys).new(*keys.map { |k| attrs[k] })
    

    Lets test it:

    p user
    p user.name
    user[:name] = 'Maria'
    p user.name
    user.name = 'Vlad'
    p user[:name]
    

    Or even OpenStruct, but be careful it will not create method if it already have it in instance methods, you can look for that by using OpenStruct.instance_methods (because of type is used, I'm now using second approach):

    attrs = {:name => 'John', :age => 22, :position => 'developer'}
    user = OpenStruct.new(attrs)
    

    Yep, so easy:

    user.name
    user[:name] # will give you an error, because OpenStruct isn't a Enumerable or Hash
    

提交回复
热议问题