Ruby 什么是课堂上的自我<&书信电报;self,为什么这与定义这段代码的类实例不同?
下面的代码试图创建一个类MyClass,该类将对方法self.add的调用委托给通过调用方法self.newAdd返回的对象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_
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