define_method 没有接收块作为参数 ruby
define_method doesn't receive block as a parameter ruby
我目前正在做 this metaprogramming tutorial 的第二周作业 1
并且在发送块以将其与 define_method 一起使用时遇到一些问题。程序根本看不到该块,当我调用 block_given 时返回 false?尽管我提供了一个块。
这是发送块的文件:
require_relative 'dog'
lassie, fido, stimpy = %w[Lassie Fido Stimpy].collect{|name| Dog.new(name)}
lassie.can :dance, :poo, :laugh
fido.can :poo
stimpy.can :dance
stimpy.can(:cry){"#{name} cried AHHHH"} # the block that I can't receive
puts lassie.name
p lassie.dance
p lassie.poo
p lassie.laugh
puts
p fido.dance
p fido.poo
p fido.laugh
puts
p stimpy.dance
p stimpy.poo
p stimpy.laugh
p stimpy.cry # method call
以及接收到的文件:
Dog = Class.new do
MESSAGES = { dance: "is dancing", poo: "is a smelly doggy!", laugh: "finds this hilarious" }
define_method :initialize do |name|
instance_variable_set(:@name, name)
end
define_method :name do
instance_variable_get :@name
end
define_method :can do |*args, &block|
puts block_given? # false
if block_given?
define_method args.to_sym do
yield
end
else
args.each do |ability|
self.class.instance_eval do
define_method "#{ability}".to_sym do
@name + " " + MESSAGES[ability]
end
end
end
end
end
define_method :method_missing do |arg|
puts "#{@name} doesn't understand #{arg}"
end
end
不确定您是否可以传递参数并阻止刚刚定义的内容。 read this
define_method(symbol, method) → symbol
define_method(symbol) { block } → symbol
而不是 define_method :can do |*args, &block|
尝试显式 def can(*args, &block)
反正这样做很奇怪..
I believe (但还没有检查) block_given?
指的是一个块被传递给由最接近的词法封闭方法定义定义的方法,即 def
,并且 不会 在使用 define_method
定义的方法中工作。
我知道一个事实,即yield
只产生一个块被传递给最接近词法封闭方法定义定义的方法,即def
,并且 不会 从一个块中产生(毕竟, define_method
是,它只是一种方法,就像任何其他采用块的方法一样,就像任何其他方法一样采取一个块,yield
屈服于方法的块,而不是其他块)。
无论如何,将 yield
和 block_given?
与显式命名的块 Proc
结合起来有点奇怪。有名字就不用匿名了,直接说
if block
define_method(args.to_sym) do block.() end
end
或者您的意思是将块传递给 define_method
以用作方法的实现?那么就是
if block
define_method(args.to_sym, &block)
end
我目前正在做 this metaprogramming tutorial 的第二周作业 1 并且在发送块以将其与 define_method 一起使用时遇到一些问题。程序根本看不到该块,当我调用 block_given 时返回 false?尽管我提供了一个块。
这是发送块的文件:
require_relative 'dog'
lassie, fido, stimpy = %w[Lassie Fido Stimpy].collect{|name| Dog.new(name)}
lassie.can :dance, :poo, :laugh
fido.can :poo
stimpy.can :dance
stimpy.can(:cry){"#{name} cried AHHHH"} # the block that I can't receive
puts lassie.name
p lassie.dance
p lassie.poo
p lassie.laugh
puts
p fido.dance
p fido.poo
p fido.laugh
puts
p stimpy.dance
p stimpy.poo
p stimpy.laugh
p stimpy.cry # method call
以及接收到的文件:
Dog = Class.new do
MESSAGES = { dance: "is dancing", poo: "is a smelly doggy!", laugh: "finds this hilarious" }
define_method :initialize do |name|
instance_variable_set(:@name, name)
end
define_method :name do
instance_variable_get :@name
end
define_method :can do |*args, &block|
puts block_given? # false
if block_given?
define_method args.to_sym do
yield
end
else
args.each do |ability|
self.class.instance_eval do
define_method "#{ability}".to_sym do
@name + " " + MESSAGES[ability]
end
end
end
end
end
define_method :method_missing do |arg|
puts "#{@name} doesn't understand #{arg}"
end
end
不确定您是否可以传递参数并阻止刚刚定义的内容。 read this
define_method(symbol, method) → symbol
define_method(symbol) { block } → symbol
而不是 define_method :can do |*args, &block|
尝试显式 def can(*args, &block)
反正这样做很奇怪..
I believe (但还没有检查) block_given?
指的是一个块被传递给由最接近的词法封闭方法定义定义的方法,即 def
,并且 不会 在使用 define_method
定义的方法中工作。
我知道一个事实,即yield
只产生一个块被传递给最接近词法封闭方法定义定义的方法,即def
,并且 不会 从一个块中产生(毕竟, define_method
是,它只是一种方法,就像任何其他采用块的方法一样,就像任何其他方法一样采取一个块,yield
屈服于方法的块,而不是其他块)。
无论如何,将 yield
和 block_given?
与显式命名的块 Proc
结合起来有点奇怪。有名字就不用匿名了,直接说
if block
define_method(args.to_sym) do block.() end
end
或者您的意思是将块传递给 define_method
以用作方法的实现?那么就是
if block
define_method(args.to_sym, &block)
end