Enable a module to define a dynamic class method

I play with Ruby and I wrote the following code:

module IdAndNameRedefine
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def use_id_and_name_from_module(use_attribute)
      class_eval <<CODE
        def id_and_name
          "\#{id}-\#{#{use_attribute}.downcase}"
        end
CODE
    end
  end
end


class Model
  include IdAndNameRedefine

  attr_reader :id, :name1, :name2

  def initialize(id, name1, name2)
    @id = id
    @name1 = name1
    @name2 = name2
  end

  def id_and_name
    "#{id}-#{name1}"
  end

  use_id_and_name_from_module :name2
end

model = Model.new(1, "TesT", "Test number TWO")
puts model.id_and_name

When I try to do here, this is to override the class method id_and_namein the Model class with the method dynamically inserted by the module IdAndNameRedefine. When this module is turned on, it creates a “static” method (indeed, the method of the Model.class class, as I understand it), and when called use_id_and_name_from_module, it creates a class method in the model that overrides id_and_nameto use any attribute specified by the model.

My question is: Is there a better way to do this, or is this the "right" way to do this? I'm not sure if I like the class class_eval, and takes a line where I need to avoid values, etc., to make this work.

+3
1

class_eval. . , , class_eval. ClassMethods :

module ClassMethods
  def use_id_and_name_from_module(use_attribute)
    class_eval do 
      define_method(:id_and_name) {"#{id}-#{send(use_attribute).downcase}"}
    end
  end
end

self class_eval, , . :

module ClassMethods
  def use_id_and_name_from_module(use_attribute)
    define_method(:id_and_name) {"#{id}-#{send(use_attribute).downcase}"}
  end
end

( , class_eval , .)

+5

Source: https://habr.com/ru/post/1710743/


All Articles