From: Brian Candler Date: 2007-03-12T19:13:37+09:00 Subject: Re: #define alternative for Ruby On Mon, Mar 12, 2007 at 06:31:02PM +0900, Michael Strelnikov wrote: > The "local variables" is exactly what confuses me. Why can't I use > variables (read/set) inside of function that is at the same hierarchy as > variable is? Because each 'def' starts a brand new scope for local variables, and local variables outside that scope are not visible. Doing this has several advantages: (1) Much more efficient to implement. - When you refer to a local variable "x" it can only be within your own stack frame, at a known offset; no need to hunt outside. - It enables the parse-time decision as to whether "x" is a local variable or method call. Otherwise this decision could only be made a run-time, and performance would suck even for simple statements like "x = y" (2) Makes it much harder to introduce unforeseen side effects by affecting local variables outside of the method you are defining. So, you may be used to writing something like x = ... def myfunc(a) .. stuff which uses x and a end in another language, but if so you'll need to think slightly differently in Ruby. When you define "functions" at the "top level" of your program, you are really defining methods inside an object called 'main'. As soon as you introduce your own objects, these problems tend to vanish, because instance variables are the de-rigeur: class Myclass def initialize(x) @x = x end def myfunc(a) .. stuff which uses @x and a end end All but the most trivial of Ruby programs declare classes like this. And there are plenty of ways of doing reflection on methods and instance variables. The simplest example is class Myclass attr_accessor :foo end which creates methods equivalent to the following: class Myclass def foo=(val) @foo = val end def foo @foo end end You can write your own analogue to attr_accessor which also sets a default value for an attribute, should you so wish, although this is usually done inside the 'initialize' method of your class. An if you're making objects with lots of attributes which vary at runtime, you'd probably be better off looking at Struct or OpenStruct as a starting point. Regards, Brian.