Рубиновый доступ к символу "Вызов" - PullRequest
0 голосов
/ 20 сентября 2009

Я хочу (эффективно) получить символ, с которым вызывается метод с псевдонимом во время выполнения. Прямой эффективный доступ к объекту стекового фрейма, чтобы получить его, был бы фантастикой

е:

класс Foo
def generic_call (* args)
put ("generic_call () был вызван с помощью # {???}")
конец

псевдоним: specific_call1: generic_call
псевдоним: specific_call2: generic_call

конец

Foo.new.specific_call1
Foo.new.specific_call2

результат, который я бы хотел


Функция generic_call () была вызвана с использованием specific_call1 ()
Функция generic_call () была вызвана с использованием specific_call2 ()

Ответы [ 4 ]

1 голос
/ 20 сентября 2009

Фрагмент кода для получения имени текущего метода:

module Kernel
    private
    # Defined in ruby 1.9
    unless defined?(__method__)
      def __method__
        caller[0] =~ /`([^']*)'/ and $1
      end
    end
  end
1 голос
/ 20 сентября 2009
class Foo
  def generic_call()
    puts "generic call was called by #{caller[0][/in `([^']+)'/, 1]}"
  end

  def specific_call1() generic_call end
  def specific_call2() generic_call end
end

Foo.new.specific_call2 # Prints: generic call was called by specific_call2

Это, однако, не будет работать, если вы используете псевдоним для создания specific_callN из generic_call, потому что методы, созданные псевдонимом, на самом деле являются копией исходного метода - на самом деле они не вызывают исходный метод (вот почему вы можете свободно переопределять оригинал, не влияя на псевдоним).

0 голосов
/ 20 сентября 2009

Может быть, вы хотите что-то подобное?

class Object
  def named_alias(name, generic_name)
    ([Class, Module].include?(self.class) ? self : self.class).class_eval do
      define_method(name) { |*args| send(generic_name, name, *args) }
    end
  end
end

class Foo
  def generic_call(f, *args)
    puts("generic_call() was called by using #{f} with #{args}")
  end

  # def specific_call1(*args)
  #     generic_call(:specific_call1, *args)
  # end
  named_alias(:specific_call1, :generic_call)
  named_alias(:specific_call2, :generic_call)
end

Foo.new.specific_call1
Foo.new.specific_call2

Отказ от ответственности: я не знаю, Ruby, я только что гуглил как там выполняют карри , затем немного адаптировали код.

0 голосов
/ 20 сентября 2009

Нет встроенного способа сделать это. Вы можете взломать это как:

def current_method_name
  caller[0].split('`').last.split('\'')[0]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...