G
Greg Weeks
I don't know how Ruby scoping works when the code involves:
nested "def"s
eval
module_eval
instance_eval
define_method
It would be nice to find an app-note for this issue. (More generally,
it would be nice to see written down how 'self' and 'klass' are used in
the Ruby execution model.)
It would also be nice to see a history of these meta-programming
constructs. (I say "meta-programming", since we're talking about code
that executes code.) I wouldn't be surprised if once upon a time Ruby
had only nested "def"s and "eval"s. However, I don't know how to write
my own version of, say, "attr_reader" using just those two. For
example, this doesn't work:
def my_attr_reader name
eval <<-STOP
def #{name}
@#{name}
end
STOP
end
I wonder if there is a way. Moving on, the following all work:
def my_attr_reader name
eval <<-STOP
define_method :#{name} do
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name
module_eval <<-STOP
def #{name}
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name
module_eval <<-STOP
define_method :#{name} do
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name # MY FAVORITE, FYI
define_method name do
p C # IGNORE FOR NOW
instance_variable_get "@"+name.to_s
end
end
Alas, There's More Than One Way To Do It. Now let's exercise those
"p C" statements:
module M
C = "M"
# INSERT ONE OF THE my_attr_reader DEFINITIONS HERE
end
class X
C = "X"
class <<X ; include M ; end
attr_writer :a
my_attr_reader :a
end
x = X.new
x.a = 4
x.a -> prints ???
With the four examples above, the printed value of C is:
"M" "X" "X" "M"
My head is swimming. Ideally, I'll find my app-note, which will clear
my mind as marvelously as "How Classes and Objects Interact" did in the
Pickaxe book.
PS: "@"+name.to_s is gross. Why doesn't "instance_variable_get" accept
an *implicit* "@"?
nested "def"s
eval
module_eval
instance_eval
define_method
It would be nice to find an app-note for this issue. (More generally,
it would be nice to see written down how 'self' and 'klass' are used in
the Ruby execution model.)
It would also be nice to see a history of these meta-programming
constructs. (I say "meta-programming", since we're talking about code
that executes code.) I wouldn't be surprised if once upon a time Ruby
had only nested "def"s and "eval"s. However, I don't know how to write
my own version of, say, "attr_reader" using just those two. For
example, this doesn't work:
def my_attr_reader name
eval <<-STOP
def #{name}
@#{name}
end
STOP
end
I wonder if there is a way. Moving on, the following all work:
def my_attr_reader name
eval <<-STOP
define_method :#{name} do
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name
module_eval <<-STOP
def #{name}
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name
module_eval <<-STOP
define_method :#{name} do
p C # IGNORE FOR NOW
@#{name}
end
STOP
end
def my_attr_reader name # MY FAVORITE, FYI
define_method name do
p C # IGNORE FOR NOW
instance_variable_get "@"+name.to_s
end
end
Alas, There's More Than One Way To Do It. Now let's exercise those
"p C" statements:
module M
C = "M"
# INSERT ONE OF THE my_attr_reader DEFINITIONS HERE
end
class X
C = "X"
class <<X ; include M ; end
attr_writer :a
my_attr_reader :a
end
x = X.new
x.a = 4
x.a -> prints ???
With the four examples above, the printed value of C is:
"M" "X" "X" "M"
My head is swimming. Ideally, I'll find my app-note, which will clear
my mind as marvelously as "How Classes and Objects Interact" did in the
Pickaxe book.
PS: "@"+name.to_s is gross. Why doesn't "instance_variable_get" accept
an *implicit* "@"?