There must be a reason it was designed this way. They must have been designed this way for a reason
Actually, I think the other way. Why should local variables be visible from within a method? A method definition is a “clean room” - I should be able to write a method definition and use that method anywhere without worrying about the context of local variables. Even in small scripts, I wouldn’t intermingle variable and method definitions in the way you did - it just seems unnatural to me. e.g. in Java, there is no option to declare local variables and methods in the mixed way that Ruby allows.
Allowing local variables to be visible inside methods opens up several complications:
-
e.g. say you gave me a method definition, and I called it. Should I have to worry about my local variable names to be able to use your method? e.g. if your method uses internally the variable i, then suddenly I cannot use the variable i because you did? How would I know that?
-
Or perhaps methods only “see” the local variables where they are defined, not where they are called? So I have to be careful where I copy-paste that method?
There’s a separate concept, the “closure”, which is a function which includes its local environment (local variables) at the point where it is defined. Closures are defined “on the fly”, when you need them in specific cases. You can see an example of a closure with do-end blocks, e.g.:
sum = 0
[1,2,3,4].each do |number|
sum += number
end
puts sum
The do-end closure includes the local environment so it can use sum. The do-end defines a (nameless) function that gets passed to tne each
method as an argument.
As @SouravGoswami has said, different languages offer different ways of doing things and different ways of thinking about problems. Which language are you most familiar with? I suspect that language has left you thinking of programs in “one way”.
To my way of thinking, Ruby’s method definitions are perfectly natural. You get a “clean room” within the method definition, but if you really, really want to work with the local environment within your method, you have closures and the scope-flattening define_method
etc techniques.