【问题标题】:Pass variables in ruby block在 ruby​​ 块中传递变量
【发布时间】:2015-04-01 05:12:49
【问题描述】:

简单的代码,不知道怎么弄:

def foo(&block)
  bar = 0
  block.call
end

foo do
  puts bar
end

如何管理块以使用来自foo 方法范围的bar 变量?

我正在尝试实现 DSL,它的功能之一是定义如何解析来自 IO 的数据并将其转换为 Request 变量。

所以我想创建这样的文件:

class FooParser < AbstractParser
  read_from_io do
    request = io.readline
  end
end

定义,read_from_io 应该如何直接工作。

所以我想,我的 AbstractParser 应该是这样的:

class AbstractParser
  def initialize
    @io = IO.new
    @request = ""
  end

  def read_from_io(&block)
    @io_reader = block
  end

  ....

  def read
    io = @io
    request = @request
    #here i want to pass io and request to block
    @io_reader.call
  end
end

【问题讨论】:

  • 这行不通。您从FooParser 中调用read_from_io,但该方法不是类方法。我不确定 DSL 是否适合这项工作。它看起来过于复杂。您可以简单地将read_from_io 实现为FooParser 中的一个方法——即def read_from_io(io)——并从AbstractParserread 方法中调用它。

标签: ruby lambda scope closures


【解决方案1】:

只需将其传递到一个块中:

def foo
  bar = 0
  yield bar
end

foo do |bar|
  puts bar
end

或者,如果您确实需要将您的块视为Proc

def foo(&block)
  bar = 0
  block.call bar
end

【讨论】:

  • 好吧,我正在尝试实现 DSL,所以我想编写一段已经具有预定义变量的代码,例如:read_from_port { request = io.readline }。所以,我认为 read_from_port 应该是这样的: def read_from_port(&block); io = @io;请求 = @request;块。调用; end #here 传递 io 并请求阻塞
  • @Virviil 你能用这些附加信息编辑你的问题吗?放在 cmets 中的代码非常不可读。
  • 对问题添加了解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-05
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多