2013-08-22 4 views
1

я получаю эту ошибку: MyModule.rb: 4: в getName': undefined local variable or method s'для MyModule: модуль (NameError)Ruby: Как получить доступ к локальным переменным модуля?

file1

module MyModule 
    s = "some name" 
    def self.getName() 
    puts s 
    end 
end 

file2

require './MyModule.rb' 

include MyModule 
MyModule.getName() 

Это что-то делать с scope, но я не понимаю, почему это происходит, если я объявлял это перед методом. включает только методы mixin, а не переменные? Как изменить модуль, чтобы он мог распечатывать переменные, которые я определяю в модуле?

+0

Пожалуйста, вы можете прочитать [стилистический справочник bbatsov в] (https://github.com/bbatsov/ruby-style-guide) и приспособиться к нему? – Hauleth

ответ

8

This has something to do with scope, but I'm not comprehending why this is happening

A def создает новый масштаб. На некоторых языках внутренняя область видимости может видеть локальные переменные в окружающей области - но не в рубине. Вы можете использовать константу вместо:

module MyModule 
    S = "some name" 

    def getName() 
    puts S 
    end 
end 

include MyModule 

getName 

--output:-- 
some name 

Но константы могут быть доступны из любой точки мира:

module MyModule 
    S = "some name" 

    def getName() 
    puts S 
    puts Dog::S 
    end 
end 

module Dog 
    S = "hello" 
end 

include MyModule 

getName 

--output:-- 
some name 
hello 

Более продвинутое решение включает в себя используя замыкание. В отличие от def, блок может видеть локальные переменные в окружающем пространстве, который известен как , замыкающий над переменными. Вот пример:

module MyModule 
    s = "some name" 
    define_method(:getName) { puts s } 
end 

include MyModule 

getName 

--output:-- 
some name 

Преимущество использования закрытия является то, что ничего, кроме блока не может получить доступ к s.

does include only mixin methods and not variables?

Это зависит от типа переменной:

module MyModule 
    A = 'hello' 
    s = 'goodbye' 
end 

include MyModule 

puts A 
puts s 

--output:-- 
hello 

1.rb:9:in `<main>': undefined local variable or method `s' for main:Object (NameError) 

module ключевое слово, как def, создает новую область. Вы знаете, как локальные переменные уничтожаются, когда метод завершает выполнение? Когда модуль завершает выполнение, ее локальные переменные уничтожаются также:

module MyModule 
    puts "MyModule is executing" 
    s = 'goodbye' 
end 

include MyModule 

puts s 

--output:-- 
MyModule is executing 

1.rb:7:in `<main>': undefined local variable or method `s' for main:Object (NameError) 
+0

Один из самых недооцененных ответов, которые я когда-либо видел. –

Смежные вопросы