如何使块局部变量成为 ruby​​ 1.9 中的默认值?

发布于 2024-08-16 09:30:42 字数 348 浏览 4 评论 0原文

Ruby 1.9 提供了定义块本地变量的能力,并且不会关闭外部作用域中同名的变量:

x = 10
proc { |;x|
    x = 20
}.call
x #=> 10

我希望将此行为作为我定义的某些块的默认行为 - 而不必使用|;x、y、z|语法(注意分号)。

我认为 Ruby 本身不允许这样做,但是是否有可能破解此功能?

我目前有一个解决方案,但它非常丑陋,因为它需要检查哪些局部变量在块末尾发生了更改,然后将它们恢复到块之前的值。我不介意您的解决方案是否需要在块的开头指定哪些变量是块本地的,即 scope(:x) { x = 20 }

Ruby 1.9 gives the ability to define variables that are just local to a block and do not close over variables of the same name in an outer scope:

x = 10
proc { |;x|
    x = 20
}.call
x #=> 10

I would like to have this behaviour as default for some blocks I define - without having to use the |;x, y, z| syntax (note the semicolon).

I do not think Ruby allows this natively but is it possible to hack this functionality?

I have one solution currently but it's quite ugly as it requires checking to see which locals have changed at the end of a block and then reverting them to their values prior to the block. I do not mind if your solution requires specifying which variables are block-local at the start of the block i.e scope(:x) { x = 20 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞陪衬 2024-08-23 09:30:42

我选择的解决方案是基于 bobbywilson0 的想法。它的工作原理如下:

x = 99
y = 98

scope { |x, y|
    x = 20
    y = 30
}

x #=> 99
y #=> 98 

这很有用,因为作用域中使用的变量是在作用域开始时创建的,并且不会关闭在其外部定义的任何变量,它们也会在作用域的开始处被 GC 回收。范围结束。

下面是实现:

def scope(&block)
    num_required = block.arity >= 0 ? block.arity : ~block.arity
    yield *([nil] * num_required)
end

该解决方案还考虑了默认值,使其在功能上等同于 lisp 中的 let*

scope { |x = 20, z = (x * 3)| 
    x #=> 20
    z #=> 60
}

我在这里写了博客: http: //banisterfiend.wordpress.com/2010/01/07/controlling-object-scope-in​​-ruby-1-9/

The solution I am choosing is based on bobbywilson0's idea. Here is how it works:

x = 99
y = 98

scope { |x, y|
    x = 20
    y = 30
}

x #=> 99
y #=> 98 

This is useful as the variables used in the scope are created at the start of the scope and do not close over any variables defined outside it, they are also GC'd at the end of the scope.

Here is the implementation:

def scope(&block)
    num_required = block.arity >= 0 ? block.arity : ~block.arity
    yield *([nil] * num_required)
end

This solution also takes default values into account making it functionally equivalent to a let* in lisp.

scope { |x = 20, z = (x * 3)| 
    x #=> 20
    z #=> 60
}

I blogged on it here: http://banisterfiend.wordpress.com/2010/01/07/controlling-object-scope-in-ruby-1-9/

无人问我粥可暖 2024-08-23 09:30:42

x = 10;过程{|x| x = 20 }.call(0)

x = 10; proc{ |x| x = 20 }.call(0)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文