Какова роль __FILE__ и __LINE__ + 1 при определении метода has_rich_text? - PullRequest
2 голосов
/ 21 марта 2019

Я нашел следующий код в Rails, но не смог понять роль __FILE__ и __LINE__ + 1. Кто-нибудь может объяснить, для чего они используются, когда вы определяете какой-то метод в class_eval, как показано ниже?

def has_rich_text(name)
  class_eval <<-CODE, __FILE__, __LINE__ + 1
    def #{name}
      self.rich_text_#{name} ||= ActionText::RichText.new(name: "#{name}", record: self)
    end

    def #{name}=(body)
      self.#{name}.body = body
    end
  CODE

  has_one :"rich_text_#{name}", -> { where(name: name) }, class_name: "ActionText::RichText", as: :record, inverse_of: :record, dependent: :destroy

  scope :"with_rich_text_#{name}", -> { includes("rich_text_#{name}") }
  scope :"with_rich_text_#{name}_and_embeds", -> { includes("rich_text_#{name}": { embeds_attachments: :blob }) }

  after_save do
    public_send(name).save if public_send(name).changed?
  end
end

1 Ответ

3 голосов
/ 21 марта 2019

Сообщение об ошибке (обратная трассировка) изменяется соответственно:

class Test
  def self.fun_ok(name)
    class_eval <<-CODE, __FILE__, __LINE__ + 1
      def #{name}; raise; end
    CODE
  end

  def self.fun_ko(name)
    class_eval <<-CODE
      def #{name}; raise; end
    CODE
  end
end

Давайте создадим методы:

Test.fun_ok("ok")
Test.fun_ko("ko")

Давайте проверим:

begin
  Test.new.ok
rescue => e
  puts e.backtrace.inspect
end
#⇒ ["/tmp/foo.rb:4:in `ok'", "/tmp/foo.rb:19:in `<main>'"]

begin
  Test.new.ko
rescue => e
  puts e.backtrace.inspect
end
#⇒ ["(eval):1:in `ko'", "/tmp/foo.rb:25:in `<main>'"]

Как вы можете видеть, первая обратная трассировка указывает на точную строку в исходном коде, которая привела к исключению (в частности: "/tmp/foo.rb:4" part.) Последняя указывает на никуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...