Ruby 什么是课堂上的自我<&书信电报;self,为什么这与定义这段代码的类实例不同?

Ruby 什么是课堂上的自我<&书信电报;self,为什么这与定义这段代码的类实例不同?,ruby,Ruby,下面的代码试图创建一个类MyClass,该类将对方法self.add的调用委托给通过调用方法self.newAdd返回的对象 class MyAdd def add(a,b) a + b end end class MyClass def self.newAdd MyAdd.new end def self.delegate(*methods, options) return unless options.has_

下面的代码试图创建一个类MyClass,该类将对方法self.add的调用委托给通过调用方法self.newAdd返回的对象

class MyAdd
      def add(a,b)
        a + b
      end
    end


class MyClass
  def self.newAdd
    MyAdd.new
  end

  def self.delegate(*methods, options)
    return unless options.has_key?(:to)

    methods.each do |method|
      define_method method, ->(*args, &prc) do
        delegated_to = self.send(options[:to])
        delegated_to.send(method, *args, &prc)
      end
    end
  end

  class << self
    debugger;
    delegate :add, to: :newAdd
  end
end
类MyAdd
def添加(a、b)
a+b
结束
结束
类MyClass
def self.newAdd
MyAdd.new
结束
def self.delegate(*方法、选项)
返回,除非选项。有_键(:to)
方法。每个do |方法|
定义方法,->(*args,&prc)do
委托给=self.send(选项[:发送])
委托给.send(方法、*args和prc)
结束
结束
结束

类下面是代码中经过修改的一部分,可以正常工作:

class MyClass
  def self.newAdd
    MyAdd.new
  end

  def self.delegate(*methods, options)
    return unless options.has_key?(:to)

    methods.each do |method|
      target = self

      define_method method, ->(*args, &prc) do
        delegated_to = target.send(options[:to])
        delegated_to.send(method, *args, &prc)
      end
    end
  end

  delegate :add, to: :newAdd
end
需要注意的是,尽量强调像
new\u add
这样的命名方法,并避免在其中使用大写字母


不能使用
const\u get
检索方法。你要找的是
方法
,但这并不总是最好的计划<代码>发送
通常就足够了。

我发布的代码的一个实际工作版本如下:

class MyAdd
  def add(a,b)
    a + b
  end
end

module Delegate
  def delegate(*methods, options)
    return unless options.has_key?(:to)

    # methods are the methods that should be delegated to 
    # the object returned by calling the method passed in options[:to]
    methods.each do |method|
      define_method method, ->(*args, &prc) do
        delegated_to = self.send(options[:to])
        delegated_to.send(method, *args, &prc)
      end
    end
  end
end

class MyClass
  extend Delegate

  def self.newAdd
    MyAdd.new
  end

  class << self
    extend Delegate
    delegate :add, to: :newAdd
  end
end
类MyAdd
def添加(a、b)
a+b
结束
结束
模块代表
def委托(*方法、选项)
返回,除非选项。有_键(:to)
#方法是应该委托给的方法
#通过调用传入选项[:to]的方法返回的对象
方法。每个do |方法|
定义方法,->(*args,&prc)do
委托给=self.send(选项[:发送])
委托给.send(方法、*args和prc)
结束
结束
结束
结束
类MyClass
扩展代表
def self.newAdd
MyAdd.new
结束
阶级

为什么self与类中的MyClass不同您上面的代码会委托一个实例方法:add to the class方法:newAdd,对吗?我的意图是将类MyClass上调用的方法:add委托给类方法:newAdd。实际上,我的意图更一般:如果我在我的单例类中调用委托方法,那么define_方法(在委托内部)将在单例类中定义一个实例方法,从而在类方法之间进行委托。如果我像您那样调用委托方法,我应该在实例方法之间进行委托。这就引出了最初的问题(与您指出的在委托内部使用const_get的错误无关):为什么我不能访问类内部的委托方法?此时,我意识到我仍然不清楚singleton类到底是什么,以及它与普通类的区别。毕竟,当我在class语句中调用define_方法时,我得到了一个实例方法,顺便说一句,当我在类中调用define_方法时,如果我没有弄错的话,我的目的是获得类似于Rails委托方法工作原理的功能。当用户向模型输入查询命令时,我在ActiveRecord中看到了类似的示例:这些命令(where、on、select等)被委托给另一个方法。该委托发生在调用
类的类中,该类委托模块代码可能很聪明,但实际上是不可读的!好的代码很容易理解,因此需要在这里进行大量重构
class MyAdd
  def add(a,b)
    a + b
  end
end

module Delegate
  def delegate(*methods, options)
    return unless options.has_key?(:to)

    # methods are the methods that should be delegated to 
    # the object returned by calling the method passed in options[:to]
    methods.each do |method|
      define_method method, ->(*args, &prc) do
        delegated_to = self.send(options[:to])
        delegated_to.send(method, *args, &prc)
      end
    end
  end
end

class MyClass
  extend Delegate

  def self.newAdd
    MyAdd.new
  end

  class << self
    extend Delegate
    delegate :add, to: :newAdd
  end
end
class MyClass
  puts self  #=> MyClass

  class <<self
    puts self  #=>MyClass’s singleton class
  end
end
class MyClass

  def self.delegate
    puts "executing MyClass.delegate()"
  end

  class <<self
    delegate 
  end

end

--output:--
1.rb:8:in `singleton class': undefined local variable or method `delegate' for #<Class:MyClass> (NameError)
  from 1.rb:7:in `<class:MyClass>'
  from 1.rb:1:in `<main>'
class MyClass

  def self.delegate
    puts "executing MyClass.delegate()"
  end

end

MyClass.delegate

--output:--
executing MyClass.delegate()
class MyClass

  class <<self
    def delegate
      puts "executing MyClass.delegate()"
    end
  end

end

MyClass.delegate

--output:--
executing MyClass.delegate()
class MyClass

  class <<self
    def delegate
      puts "executing MyClass.delegate()"
    end

    delegate
  end

end
class <<self
  def delegate
    puts "executing MyClass.delegate()"
  end

  delegate
end
class Dog
  def bark
    puts “woof”
  end

  bark
end
1.rb:7:in `<class:Dog>': undefined local variable or method `bark' for Dog:Class (NameError)
    from 1.rb:1:in `<main>'
class Dog
end

s1 = Dog.singleton_class
puts s1  

s2 = s1.singleton_class
puts s2

s3 = s2.singleton_class
puts s3

--output:--
#<Class:Dog>
#<Class:#<Class:Dog>>
#<Class:#<Class:#<Class:Dog>>>
class Dog
  class <<self  #s1
    class <<self #s2
      def greet  #Instances of s2 can call greet, and the only instance of s2 is s1.
        puts "hello"
      end
    end
  end
end


class Dog
  class <<self
    #Inside here self = Dog's singleton class = s1
    greet  #equivalent to Dogs_singleton_class.greet
  end
end

--output:--
hello