Scope limitation causes problems for me

hi, everyone.

I have the following codes.

m = Hash.new(“merong”)

m[“b”] = “babo”

def func
begin
m[“a”] = “merong”
rescue => e
puts e
end
end

func

exception is

undefined local variable or method `m’ for main:Object

Could I know the reason this was caused??

You either need to pass m as a parameter

def func(m)
begin
m[“a”] = “merong”
rescue => e
puts e
end
end

and call it like

func(m)

or make m global

$m = Hash.new(“merong”)

$m[“b”] = “babo”

def func
begin
$m[“a”] = “merong”
rescue => e
puts e
end
end

func

I recommend the first way

On Tue, Apr 13, 2010 at 5:41 PM, 김준영 [email protected] wrote:

    m[“a”] = “merong”

undefined local variable or method `m’ for main:Object

Could I know the reason this was caused??

The reason is that the def keyword starts a new scope, and doesn’t
inherit the surrounding scope (it’s not a closure). You could pass the
hash as a parameter to the function for example:

m = Hash.new(“merong”)
m[“b”] = “babo”

def func hash
begin
hash[“a”] = “merong”
rescue => e
puts e
end
end

func m

Or use define_method, if you really wanted a closure over that scope:

m = Hash.new(“merong”)
m[“b”] = “babo”

self.class.send (:define_method, :func) do
begin
m[“a”] = “merong”
rescue => e
puts e
end
end

func

Jesus.

On Apr 13, 2010, at 8:41 AM, ±èÁØ¿µ wrote:

   m["a"] = "merong"

undefined local variable or method `m’ for main:Object

Could I know the reason this was caused??

In your code, m is defined as a local variable in the top scope, so it
is not visible in methods. A straightforward fix would be to use $m
instead of m, which will designate a global variable. However, I would
strongly recommend to wrap your code in a class and have an instance
variable @m which will be visible to every method of that class, thus
avoiding evil global variables:

class Performer
def initialize(default_value)
@m = Hash.new(default_value)
@m[“b”] = “babo”
end

def func
begin
@m[“a”] = “merong”
rescue => e
puts e
end
end
end

Then you can call it as:

Performer.new(“merong”).func

Gennady.