Ruby accessing outer variables in nested function
As far as I know, defining a named function within a function does not give you access to any local variables.
What you can do instead is use a Proc:
def foo(x)
bar = lambda do
puts x
end
bar.call
42
end
foo(5)
Can you access Ruby variables with outer scope inside of methods?
This is a duplicate of Ruby accessing outer variables in nested function.
You could make it an instance variable on the containing object by calling it @rotation
, but why not just pass string
and rotation
into the encrypt
method?
Inner function in Ruby
A Ruby lambda
is similar to an anonymous js function
:
step1 = lambda {puts "I am a lambda!"}
step1.call "optional args", ...
Some shorthand:
f = -> {puts "Shorthand lambda"}
f.()
More info (including shorthand notation!!) here
Understanding Ruby Nested Functions
It's something called the "scope gate". Basically, when you start a definition of a method/class/module, a new scope is created and all local variables from other scopes can't be accessed. This doesn't apply to instance/global variables, you'll keep access to those.
Since a lambda isn't a method, it doesn't create new scope and reuses existing one instead.
Also,
why line 3 works
x = 123
def b(x)
p x # this "x" is "x the parameter", not "x the local variable from outer scope"
# that's why it works. If you tried to access the local var, it wouldn't work.
def a(u)
p x # like here, see? Doesn't work.
end
a 4
end
b 1
In Ruby, how can inner class access variables/methods defined in outer class?
In Ruby, how can inner class access variables/methods defined in outer class?
Ruby does not have a concept of "inner" or "outer" classes. It sounds like you are coming from a language like BETA, Scala, or Newspeak, but Ruby is not BETA, Scala, or Newspeak. As a general rule, any programming language works exactly how the specification for the programming language says it works, not how the specification for some other programming language says it works. BETA, Scala, and Newspeak have nested classes, but Ruby has not.
In Ruby, you can lexically nest a class definition, but that does not create a nested class. If you nest the definition of a class inside the definition of another class, that does not create any sort of relationship whatsoever between those two classes. None. You cannot "access variables/methods" of one class from the other class because there is no relationship between those two classes you could follow in order to get at those variables/methods.
The only thing a nested class definition does, is namespace the constant defined by the inner class definition to the outer class. That's it. There is no relationship between the two classes, the only relationship is between the constant and the class.
It is just not possible.
The way to create relationships between classes in Ruby is inheritance, not nesting (because there is no nesting). The way to create relationships between objects in Ruby is association, aggregation, or composition, not nesting.
Ruby is flexible enough to implement something that behaves like a "proper" BETA-style inner class. Remember, an inner class is "nested" inside an object instance of the outer class. We can emulate that using an instance variable:
class Outer
attr_reader :Inner
def outer_method
__callee__
end
private
attr_writer :Inner
def initialize
self.Inner = Class.new(self.class) do
def inner_method
[__callee__, outer_method]
end
end
end
end
outer = Outer.new
inner = outer.Inner.new
p inner.inner_method
Please note that I made the inner class inherit from the outer class: that is the way to do behavior sharing in Ruby. You need to have some form of inheritance or association relationship. The nesting does not create a relationship.
how to access a class variable of outer class from inner class in ruby
The only way to access this class variable is via an accessor method
class A
def self.lock
@@lock ||= Monitor.new
end
class B
def method
A.lock.synchronize
puts "xxxxx"
end
end
end
end
How do I set a local variable declared in a nested method to be within the parent method's scope?
Set the result of the proc to old_var
so that it’s declared on the same scope where used.
old_var =
@sandbox.function() do |resp|
resp.var.to_f
end
The same for new_var
:
new_var =
@sandbox.function() do |resp|
resp.var.to_f
end
How do I set a local variable declared in a nested method to be within the parent method's scope?
Answering the question in the title: that is impossible.
If you need to perform some actions before returning a value from a nested block, use break
:
value =
@sandbox.function() do |resp|
foo = 42
# do something else
break foo
end
Let inner function use arguments of outer function
1) Define the inner function inside the outer function and the inner function will have access to the outer function's variables. Here inner
uses a
from outer
even though a
was not passed to inner
.
outer <- function(a, x) {
inner <- function(y) {
a + y
}
inner(2 * x)
}
# test
outer(10, 100)
## [1] 210
2) Alternately, inject inner
into outer
like this:
inner <- function(y) {
a + y
}
outer <- function(a, x) {
environment(inner) <- environment()
inner(2 * x)
}
# test
outer(10, 100)
## [1] 210
Related Topics
Ruby Way to Generate a Hmac-Sha1 Signature for Oauth
Reraise (Same Exception) After Catching an Exception in Ruby
How to Access Url Helper from Rails Module
How to Drop to the Irb Prompt from a Running Script
How to Find the Path a Ruby Gem Is Installed at (I.E. Gem.Lib_Path C.F. Gem.Bin_Path)
What Does the "Yield" Keyword Do in Ruby
How to Change Hash Keys from 'Symbol's to 'String'S
What Are the Differences Between Rbenv, Rvm, and Chruby
Rails: Hasmanythroughassociationnotfounderror
Ruby 1.9, Force_Encoding, But Check
How to Use Ruby Dbi's 'Select_All' VS 'Execute-Fetch/Each-Finish'
How to Save Unescaped & in Nokogiri Xml