Local variable and closure

Hello,

below is one little script that fails at ### <<< line
the output is

Animal has properties
Animal will be speakable
Dog has properties
Dog will be speakable
Duck has properties
Duck will be speakable
…/dort.rb:16:in speak': undefined local variable or methodmsg’ for
#Dog:0x401d8da0 (NameError)
from ./dort.rb:44

I would think that (passed to function) local variable msg would be
“closed” in self.class_eval {} closure and therefor be accessable

can someone point out why it doesn’t work?

Regards, Daniel

#!/usr/bin/env ruby

$prop = {}

def prop
puts “#{self.name} has properties”
self.class_eval do
$prop[self] = []
end
end

def speakable(msg)
puts “#{self.name} will be speakable”
self.class_eval do
$prop[self] << “I can speak”
def speak;msg;end ### <<<
end
end

class Animal
prop
speakable “…”
def whatCanIDo;$prop[self.class];end
def self.whatCanIDo;$prop[self];end
end

class Dog < Animal
prop
speakable “wuff”
end

class Duck < Animal
prop
speakable “quak”
end

a = Dog.new
b = Duck.new

puts a.speak, b.speak

Schüle Daniel wrote:

Duck will be speakable

end
prop
class Duck < Animal
prop
speakable “quak”
end

a = Dog.new
b = Duck.new

puts a.speak, b.speak

Without looking too close at your code: def has special scoping rules.
You better try to use define_method:

def speakable(msg)
class_eval do
# …
define_method(:speak) msg end
end
end

HTH

Btw, what are you trying to accomplish? Somehow I have the feeling that
your code might be more complex than needed. Especially the use of a
global variable irritates me.

Kind regards

robert

Hello Robert,

Btw, what are you trying to accomplish? Somehow I have the feeling that
your code might be more complex than needed. Especially the use of a
global variable irritates me.

complexity was the intention of my code :slight_smile:
no really, I am playing with metaprogramming, also I wanted to know how
to implement own functions like “attr_accessor”
btw is there special name for this kind of functions?
functions that are executed in the class scope and can refer with “self”
to the class they are inside.

Regards, Daniel

Schüle Daniel wrote:

Hello Robert,

Btw, what are you trying to accomplish? Somehow I have the feeling
that your code might be more complex than needed. Especially the
use of a global variable irritates me.

complexity was the intention of my code :slight_smile:

:slight_smile:

no really, I am playing with metaprogramming, also I wanted to know
how to implement own functions like “attr_accessor”

One way:

class Module
def i_am_in_class_scope(*a)
p a
end
end

class Foo
i_am_in_class_scope :foo, :bar
end
[:foo, :bar]
=> nil

btw is there special name for this kind of functions?
functions that are executed in the class scope and can refer with
“self” to the class they are inside.

I’d call them “class instance methods”.

Kind regards

robert