How to make local block variable variables by default in ruby ​​1.9?

Ruby 1.9 allows you to define variables that are only local to a block, and not to close variables with the same name in the outer scope:

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

I would like this behavior to be the default for some blocks that I define - without using |; x, y, z | syntax (note the semicolon).

I don't think Ruby allows this initially, but can this functionality be hacked?

I have one solution at the moment, but it is pretty ugly as it requires checking which locales changed at the end of the block and then returning them to their values ​​before the block. I do not mind if your decision requires you to specify which variables are block-local at the beginning of the ie blockscope(:x) { x = 20 }

+3
source share
2 answers

The solution I choose is based on the idea of ​​bobbywilson0. Here's how it works:

x = 99
y = 98

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

x #=> 99
y #=> 98 

This is useful because the variables used in scopeare created at the beginning 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 into account default values, which makes it functionally equivalent let*in lisp.

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

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

+6
source

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

+4
source

Source: https://habr.com/ru/post/1727287/


All Articles