If a block is a closure, why does this code does not work, and how to make it work?
def R(arg)
Class.new do
def foo
puts arg
end
end
end
class A < R("Hello!")
end
A.new.foo #throws undefined local variable or method `arg' for #<A:0x2840538>
Some people also have a need to avoid closure. The need to avoid closure is born from a person's desire to avoid commitment or confrontation. In other words, someone avoiding closure doesn't want certain questions answered. They might be afraid of what they'll learn.
Closure is important after a breakup because: Your brain needs an authentic narrative to make sense of what happened. Without closure you might keep going back to a relationship that wasn't working. You could be doomed to repeat the same relationship patterns the next time around without closure.
When You Can't Get Closure. In many instances, closure may not be an option. For example, if someone has passed away, you cannot receive closure. If a romantic relationship has ended, the other person may be unwilling or unable to give you the closure you need.
Blocks are closures and arg
is indeed available inside the Class.new
block. It's just not available inside the foo
method because def
starts a new scope. If you replace def
with define_method
, which takes a block, you'll see the result you want:
def R(arg)
Class.new do
define_method(:foo) do
puts arg
end
end
end
class A < R("Hello!")
end
A.new.foo # Prints: Hello!
If you define the class dynamically, you can alter it as you like:
def R(arg)
c = Class.new
# Send the block through as a closure, not as an inline method
# definition which interprets variables always as local to the block.
c.send(:define_method, :foo) do
arg
end
c
end
class A < R("Hello!")
end
puts A.new.foo.inspect
# => "Hello!"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With