【问题标题】:Ruby block variable scoping issue?Ruby块变量范围问题?
【发布时间】:2012-02-22 16:41:01
【问题描述】:

我目前在这方面遇到了困难,我似乎找不到错误,但我认为这与 Ruby 块范围规则有关。我在这里阅读了很多帖子,但它们似乎与我遇到的问题并不相似(或者我可能太笨了,看不到它)。我有一个服务器对象,目前只有两个实例变量(主机名和操作系统)定义了 setter/getter。

问题是我在读取 ssh 通道数据的块中间定义了一个服务器对象的操作系统。我知道通道具有正确的数据,因为当我运行脚本时,它会正确打印出“放置本地操作系统”行,但是当它到达 ch.exec 块的末尾时,Server.getOS 已变回零。

有什么想法吗?

注释和代码: “hosts”是一个服务器对象数组。

hosts.each do |server|
begin 
    Net::SSH.start(server.getHostname, user , :password => password , :port=> port) do |ssh|
        channel = ssh.open_channel do |ch|
            ch.exec "uname" do |chan, success|
                raise "could not execute uname command" unless success
                chan.on_data do |c, data|
                    server.setOS = data
                    puts "local OS:  #{server.getOS}"
                    # server.getOS = "AIX" here
                end
                chan.on_extended_data do |c, type, data|
                    puts data
                end
            end

            puts "OS:  #{server.getOS} -- hostname: #{server.getHostname}"
            # server.getOS = "" here.. 

.. 并从那里开始基于 server.getOS 的处理,但 server.getOS 为 nil。

【问题讨论】:

    标签: ruby


    【解决方案1】:

    目前尚不清楚这里发生了什么,但可能的候选者不是范围界定,因为这会触发其他类型的错误,而是操作顺序。如果这是一个异步操作,您的exec 块可能会在代码中的puts 调用之后执行。

    请记住,在 Ruby 中定义的块可以在任何时间点执行零次或多次。无法保证它们会立即执行,并且预计它们在进行异步操作时至少会延迟一小段时间。

    请注意,getXsetX 的使用违背了 Ruby 的特点,其中 xx= 是常规使用的方法。 Ruby 中以 = 结尾的方法名称被假定为修改器。

    【讨论】:

    • “请记住,块......不保证它们会立即执行。”如果这是真的,那么您将如何保证任何程序按预期工作?我可能误解了你,但这条评论读起来就像 Ruby 移动我的块并随机执行它们。 2+3*6 应始终等于 20。
    • 当你向一个方法提供一个 Ruby 块时,你不知道该块是否或何时会被执行。您必须熟悉该方法提供的“合同”并采取相应的行动。例如,迭代器会立即运行您的方法 N 次,大多数异步回调方法将被调用一次,但您不知道何时,有些可能因为某些条件根本不执行您的方法。它不是随机的,它基本上是可预测的,但是一旦你提供了一个块,你就会受到你给它的调用方法的支配。
    • 在您给出的情况下,该块只能在连接完成时执行。您必须熟悉该方法设置的期望。据推测,on_data 方法的块仅在接收到数据时执行,并且在您的初始 puts 在 CPU 时间尺度中执行之后,这可能是永恒的。
    • @codecompleting Toronto 有一个很大的 Rails 社区,你为什么要问这个问题?
    • @tadman 只是好奇,我没有看到很多广告。想知道合约市场主要是如何...
    猜你喜欢
    • 2011-10-20
    • 2018-04-08
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2011-11-21
    • 2011-04-13
    相关资源
    最近更新 更多