首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Ruby中使用"send“调用跨对象的方法的技术是什么?

在Ruby中使用"send“调用跨对象的方法的技术是什么?
EN

Stack Overflow用户
提问于 2015-05-13 01:48:49
回答 2查看 34关注 0票数 0

我正在进行一些涉及Ruby中异步回调的编程,并且需要将回调方法传递给另一个对象(该对象可能被静态调用,也可能不被静态调用)。我的问题是对实例的回调的语法-我知道它相当复杂,但我不确定我是否可以使它更简单。我现在拥有的是:

代码语言:javascript
运行
复制
class OBJA
  def self.staticMethod(text, returnCall)
    puts "objA.staticMethod: #{text}"
    OBJB.send(returnCall, "Call back from objA.staticMethod")
  end

  def instanceMethod(text, returnCall)
    puts "objA.instanceMethod: #{text}"
    OBJB.send(returnCall, "Call back from objA.instanceMethod")
  end
end

class OBJB
  def starterMethod
    OBJA.staticMethod("foo", :returnedCall)
    OBJA.new.instanceMethod("bar", :returnedCall)
  end

  def returnedCall(text)
    puts text
  end
end

您可以执行以下操作:

代码语言:javascript
运行
复制
b = OBJB.new
b.starterMethod

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-13 01:59:56

我遇到的问题是实例回调的语法。

您必须用实例调用实例方法。如果在类上调用类方法,例如OBJB.send(...),则必须定义类方法。

代码语言:javascript
运行
复制
class OBJA
  def self.staticMethod(text, methName)
    puts "objA.staticMethod: #{text}"
    OBJB.send(methName, "Call back from objA.staticMethod")
  end

  def instanceMethod(text, methName)
    puts "objA.instanceMethod: #{text}"
    OBJB.new.send(methName, "Call back from objA.instanceMethod")
  end
end


class OBJB
  def starterMethod
    OBJA.staticMethod("foo", :returnedCall)
    OBJA.new.instanceMethod("bar", :returnedCall)
  end

  def self.returnedCall(text)
    puts text
  end

  def returnedCall(text)
    puts text
  end
end

b = OBJB.new
b.starterMethod

--output:--
objA.staticMethod: foo
Call back from objA.staticMethod
objA.instanceMethod: bar
Call back from objA.instanceMethod

还可以将块传递给OBJA方法:

代码语言:javascript
运行
复制
class OBJA
  def self.staticMethod(text, &block)
    puts "objA.staticMethod: #{text}"
    block.call("Call back from objA.staticMethod")
  end

  def instanceMethod(text, &block)
    puts "objA.instanceMethod: #{text}"
    block.call("Call back from objA.instanceMethod")
  end
end


class OBJB
  def starterMethod
    OBJA.staticMethod("foo") {|str| puts str}
    OBJA.new.instanceMethod("bar") {|str| puts str}
  end
end

b = OBJB.new
b.starterMethod

--output:--
objA.staticMethod: foo
Call back from objA.staticMethod
objA.instanceMethod: bar
Call back from objA.instanceMethod

或者,更能说明这一结束:

代码语言:javascript
运行
复制
class OBJA
  def self.staticMethod(text, &block)
    puts "objA.staticMethod: #{text}"
    block.call
  end

  def instanceMethod(text, &block)
    puts "objA.instanceMethod: #{text}"
    block.call
  end
end


class OBJB

  def initialize
    @x = 1
    @y = 2
  end

  def starterMethod
    OBJA.staticMethod("foo") {puts instance_variable_get(:@x)}
    OBJA.new.instanceMethod("bar") {puts instance_variable_get(:@y)}
  end
end

b = OBJB.new
b.starterMethod

--output:--
objA.staticMethod: foo
1
objA.instanceMethod: bar
2

我不知道这是否会对您有所帮助,但是这个技巧在Ruby框架中得到了广泛应用。Ruby是编程语言的西部,它实际上允许您忽略闭包。当您想接受某个代码中的块时,这是很有用的,但是您不希望在定义了块的上下文中执行块--而是希望在您创建的上下文中执行该块。

代码语言:javascript
运行
复制
class OBJA
    @x = 10  #Instance variables attach themselves to whatever object is
    @y = 20  #self at the time they are created.  Inside a class, but outside
             #any defs, self is equal to the class, so these statements
             #create  what are known as 'class instance variables' (@@variables
             #aren't used in ruby because they don't behave 'correctly').


  def self.staticMethod(text, &block)
    puts "objA.staticMethod: #{text}"
    instance_eval &block  #See comment (1) below
  end

  def instanceMethod(text, &block)
    puts "objA.instanceMethod: #{text}"
    block.call
  end
end


class OBJB

  def initialize
    @x = 1
    @y = 2
  end

  def starterMethod
    OBJA.staticMethod("foo") {puts instance_variable_get(:@x)}
    OBJA.new.instanceMethod("bar") {puts instance_variable_get(:@y)}
  end
end

b = OBJB.new
b.starterMethod

--output:--
objA.staticMethod: foo
10  #<--CHECK THIS OUT!!
objA.instanceMethod: bar
2

(1)当您调用一个没有接收者的方法时,ruby使用self来调用该方法。在类方法中,self等于类,因此instance_eval()调用等效于:

代码语言:javascript
运行
复制
 OBJA.instance_eval &block

instance_eval()用于将自变量的值更改为接收方。但赛尔夫已经和OBJA平等了?instance_eval()成功地做的是改变它的块看到的自变量的值!通过将块变量转换为instance的块,您实际上更改了块上下文,即块的代码所看到的变量。

票数 2
EN

Stack Overflow用户

发布于 2015-05-13 02:02:49

目前在类中调用回调OBJB.send,但是returnedCall方法是一个实例方法。有两种方法可以解决这个问题:

通过将OBJB.send(...行更改为

代码语言:javascript
运行
复制
OBJB.new.send(...

或将回调方法改为类方法,将def returnedCall(...更改为

代码语言:javascript
运行
复制
def self.returnedCall(text)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30204278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档