Ruby can not access variable outside the method?
The result
and template
variables inside the generateMethods
function are different from the ones declared outside and are local to that function. You could declare them as global variables with $
:
$template=<<MTEMP
#methodName#:function(){},
MTEMP
$result="";
def generateMethods(mds)
mds.each do |md|
$result+=$template.gsub(/#methodName#/,md).to_s+"\n";
end
$result;
end
puts generateMethods(['getName','getAge','setName','setAge'])
But what's your purpose with this function? I think there's a cleaner way to do this if you can explain your question more.
Why can't I access a local variable inside a method in Ruby?
The reason ff
is inaccessible inside the test
method definition is simply that methods (created with the def
keyword) create a new scope. Same with defining classes and modules using the class
and module
keywords respectively.
The role of main
(the top-level object) is almost completely irrelevant to the question of scope in this situation.
Note that, if you DO want your test
method to have access to locals defined in the definition context, then use the define_method
(or in your case, the define_singleton_method
method), see here:
ff = "hi"
define_singleton_method("test") { ff }
test #=> "hi"
Unlike the def
keyword, the define_method
family of methods do not create new scopes but instead close over the current scope, capturing any local variables.
The reason using @ff
worked in the next example given by @soup, is not that main
is somehow a "special case" it's just that an ivar defined at top-level is an ivar of main
and so is accessible to a method invoked on main
.
What, however, is the relationship of the test
method to main
? It is not a method on just main
itself - it is actually a private instance method defined on the Object
class. This means that the test
method would be available (as a private method) to nearly every object in your ruby program. All methods defined at top-level (main
) are actually defined as private instance methods on the Object
class.
For more information on the Ruby top-level, see this article: http://banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/
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?
Ruby struct creation block cannot access variable outside the block
It's because def
keyword starts new local variables scope, so default
local variable isn't visible inside of it. The workaround is to use define_method
, because the block you pass into it is closure:
default = 'test'
A = Struct.new(:a, :b) do
define_method(:initialize) do |*args|
super(*args)
self.b ||= default
end
end
a = A.new
a.b
# => "test"
Why can I refer to a variable outside of an if/unless/case statement that never ran?
It's because of how the Ruby parser works. Variables are defined by the parser, which walks through the code line-by-line, regardless of whether it will actually be executed.
Once the parser sees x =
, it defines the local variable x
(with value nil
) henceforth in the current scope. Since if
/unless
/case
/for
/while
do not create a new scope, x
is defined and available outside the code block. And since the inner block is never evaluated as the conditional is false, x
is not assigned to (and is thus nil
).
Here's a similar example:
defined?(x) and x = 0
x #=> nil
Note that this is a rather high-level overview of what happens, and isn't necessarily exactly how the parser works.
Unable to access instance variable outside the class in ruby
In order to print an instance variable, you must access it with the context of the instance.
p @obj.stacks
Ruby: Changing the variable outside the method
In your example you always create new binding (context) by calling foo
. That is why changes are lost.
It should work if you call the same binding
b = foo
b.local_variable_get(:a) # => 1
eval("a = 2", b)
b.local_variable_get(:a) # => 2
b.local_variable_set(:a, 3)
b.local_variable_get(:a) # => 3
Is there a way to access a local variable defined inside a block outside the block?
binding
returns a new instance every time you call it. You have to send eval
to the same binding in order to access local variables that you've created earlier:
def create(code, b = binding)
width = code.each_line.map(&:length).max
code.each_line.map do |line|
'%-*s #=> %s' % [width, line.chomp, b.eval(line)]
end
end
puts create <<~'RUBY'
baz, qux = 5, 3
baz
qux
RUBY
Output:
baz, qux = 5, 3 #=> [5, 3]
baz #=> 5
qux #=> 3
Note that in the above example, binding
will make the method's local variables available to the block:
create 'local_variables'
#=> ["local_variables #=> [:code, :b, :width]"]
You might want to create a more restricted evaluation context, e.g. (replicating Ruby's main)
def empty_binding
Object.allocate.instance_eval do
class << self
def to_s
'main'
end
alias inspect to_s
end
return binding
end
end
def create(code, b = empty_binding)
# ...
end
Related Topics
How to Update Rails Locale Yaml File Without Loosing Comments and Variables
Why Do Ruby Procs/Blocks with Splat Arguments Behave Differently Than Methods and Lambdas
Grouping Consecutive Numbers in an Array
Exec': String Contains Null Byte (Argumenterror)
Trying to Set Up Amazon's S3 Bucket: 403 Forbidden Error & Setting Permissions
How to Split a String into Consecutive Substrings of Length at Most 3 in All Possible Ways
How to Search Array Through Ransack Gem
Grouped Collection Select Alphabetical Order Rails
How to Deal with App_Key and App_Secret (Dropbox API)
Need to Use Add_Index on Migration for Belongs_To/Has_Many Relationship? (Rails 3.2, Active Record)
Kill Process and Sub-Processes in Ruby on Windows
Rvm System-Wide Install Script Url Broken -- What Is Replacement
Programmatically Derive a Regular Expression from a String
What Is the Purpose of the Enumerator Class in Ruby
Why Does a Simple Thin Server Stop Responding at 16500 Requests When Benchmarking
Convert Timestamp Timezone in Logstash for Output Index Name
Phonegap Mobile Rails Authentication (Devise? Authentication from Scratch)