Ruby переменная область видимости убивает меня - PullRequest
0 голосов
/ 14 октября 2010

У меня есть парсер, который читает файлы.Внутри файла вы можете объявить имя файла, и синтаксический анализатор пойдет и прочитает его, затем, когда это будет сделано, возьмет его с того места, где он остановился, и продолжит.Это может произойти столько уровней, сколько вы хотите.

Звучит довольно просто.Все, что я хочу сделать, это распечатать имена файлов и номера строк.

У меня есть класс с именем FileReader, который выглядит следующим образом:

class FileReader
    attr_accessor :filename, :lineNumber
    def initialize(filename)
        @filename = filename
        @lineNumber = 0
    end
    def readFile()
        # pseudocode to make this easy
         open @filename
         while (lines)
             @lineNumber = @lineNumber + 1
             if(line startsWith ('File:'))
                 FileReader.new(line).readFile()
             end
             puts 'read ' + @filename + ' at ' + @lineNumber.to_s()
         end
         puts 'EOF'
    end
end

Достаточно просто.Допустим, у меня есть файл, который ссылается на другие файлы, подобные этому.File1-> File2-> file3.Вот как это выглядит:

read File1 at 1
read File1 at 2
read File1 at 3
read File2 at 1
read File2 at 2
read File2 at 3
read File2 at 4
read File3 at 1
read File3 at 2
read File3 at 3
read File3 at 4
read File3 at 5
EOF
read File3 at 5
read File3 at 6
read File3 at 7
read File3 at 8
EOF
read File2 at 4
read File2 at 5
read File2 at 6
read File2 at 7
read File2 at 8
read File2 at 9
read File2 at 10
read File2 at 11

И это не имеет никакого смысла для меня.

File 1 has 11 lines
File 2 has 8 lines
File 3 has 4 lines

Я бы предположил, что создание нового объекта будет иметь свою собственную область, которая невлияет на родительский объект.

Ответы [ 3 ]

2 голосов
/ 14 октября 2010
class FileReader
  def initialize(filename)
    @filename = filename
  end

  def read_file
    File.readlines(@filename).map.with_index {|l, i|
      next "read #{@filename} at #{i}" unless l.start_with?('File:')
      FileReader.new(l.gsub('File:', '').chomp).read_file
    }.join("\n") << "\nEOF"
  end
end

puts FileReader.new('File1').read_file

или просто

def File.read_recursively(filename)
  readlines(filename).map.with_index {|l, i|
    next "read #{filename} at #{i}" unless l.start_with?('File:')
    read_recursively(l.gsub('File:', '').chomp)
  }.join("\n") << "\nEOF"
end

puts File.read_recursively('File1')
0 голосов
/ 14 октября 2010

Это то, что я придумал.Это не красиво, но я старался держаться как можно ближе к вашему коду, пока Ruby его запечатлел.

file_reader.rb

#!/usr/bin/env ruby
class FileReader

  attr_accessor :filename, :lineNumber

  def initialize(filename)
      @filename = filename
      @lineNumber = 0
  end

  def read_file
    File.open(@filename,'r') do |file|
      while (line = file.gets)
        line.strip!
        @lineNumber += 1
        if line.match(/^File/)
          FileReader.new(line).read_file()
        end
        puts "read #{@filename} at #{@lineNumber} : Line = #{line}"
      end
    end
    puts 'EOF'
  end
end

fr = FileReader.new("File1")
fr.read_file

И File1, File2 и File3 выглядят как:

Line 1
Line 2
Line 3
File2 
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
Line 11

Вывод:

read File1 at 1 : Line = Line 1
read File1 at 2 : Line = Line 2
read File1 at 3 : Line = Line 3
read File2 at 1 : Line = Line 1
read File2 at 2 : Line = Line 2
read File2 at 3 : Line = Line 3
read File2 at 4 : Line = Line 4
read File3 at 1 : Line = Line 1
read File3 at 2 : Line = Line 2
read File3 at 3 : Line = Line 3
read File3 at 4 : Line = Line 4
EOF
read File2 at 5 : Line = File3
read File2 at 6 : Line = Line 6
read File2 at 7 : Line = Line 7
read File2 at 8 : Line = Line 8
EOF
read File1 at 4 : Line = File2
read File1 at 5 : Line = Line 5
read File1 at 6 : Line = Line 6
read File1 at 7 : Line = Line 7
read File1 at 8 : Line = Line 8
read File1 at 9 : Line = Line 9
read File1 at 10 : Line = Line 10
read File1 at 11 : Line = Line 11
EOF

Чтобы повторить, мы действительно должны увидеть ваш код, чтобы узнать, где проблемы.

Я понимаю, вы думаете, что у него что-то естьделать с переменной областью видимости, поэтому вопрос имеет смысл для меня.

Для других людей.Пожалуйста, будьте немного более добры к новичкам, пытающимся учиться.Это должно быть место для помощи.Спасибо.

0 голосов
/ 14 октября 2010

Я согласен, что что-то в вашем коде переписывания запутало проблему. Да, эти переменные экземпляра должны быть локальными для экземпляра.

Остерегайтесь вещей, где блок кода или условного выражения может возвращать значение и присваивать его переменной экземпляра ... например, если ваш оператор open использует следующий блок и каким-то образом возвращает имя файла ... @filename = открыть (строка) {}

Я говорю это, потому что имя файла, очевидно, не изменилось после EOF

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...