Вопрос

Я строю лексико-анализатор в Ruby и собираюсь начать собираться и хранить символы в таблице символов. Мой главный вопрос о дизайне символа и относительно того, должен ли оно статическую таблицу (что означает, что все данные будут проводиться на уровне класса) или должны быть ли он на экземпляре.

Вариант 1: Структура данных уровня класса

require 'SymbolTableEntry.rb'

class SymbolTable
  @sym_table = Array.new(500)
  def initialize()
  end

  def SymbolTable.add(element, index)
    @sym_table[index] = element if element.is_a? SymbolTableEntry
  end

  def SymbolTable.to_s
    pp @sym_table
  end
end
.

С этой схемой класс SymbStable имеет своего рода «статическую» функциональность, что означает, что я на самом деле не создаю экземпляр символ, единственный объект, который существует, - это уровень класса.

(предположим, что SymbolTableEntry является действительным объектом, даже если я не определяю это здесь)

ex:

irb(main):002:0> require 'SymbolTable.rb'
=> true

irb(main):003:0> ste = SymbolTableEntry.new
=> #<SymbolTableEntry:0x7ef36884>

irb(main):004:0> SymbolTable.add(ste, 10)
=> #<SymbolTableEntry:0x7ef36884>

irb(main):005:0> SymbolTable.to_s
[nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 #<SymbolTableEntry:0x7ef36884>]
=> nil
.

Вариант 2: Структура данных уровня экземпляра

require 'rubygems'
require 'backports'
require 'SymbolTableEntry.rb'

class SymbolTable
  def initialize()
    @sym_table = Array.new(10)
  end

  def add(element, index)
    @sym_table[index] = element if element.is_a? SymbolTableEntry
  end

  def to_s
    pp @sym_table
  end
end
.

С этой схемой мне действительно нужно создать экземпляр класса символов, чтобы добавить значения в таблицу символов.

irb(main):001:0> require 'SymbolTable.rb'
=> true

irb(main):002:0> st = SymbolTable.new
=> #<SymbolTable:0x7eeb6c9c @sym_table=[nil, nil, nil, nil, nil, 
                                        nil, nil, nil, nil, nil]>

irb(main):003:0> ste=SymbolTableEntry.new
=> #<SymbolTableEntry:0x7eeb4d5c>

irb(main):004:0> st.add(ste,10)
=> #<SymbolTableEntry:0x7eeb4d5c>

irb(main):007:0> st.to_s
[nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 nil,
 #<SymbolTableEntry:0x7eeb4d5c>]
=> nil
.

Я хотел бы услышать любой и все входные данные, на которые вы будете использовать или предпочесть использовать любые комментарии по Ruby Code в целом.

Спасибо

Это было полезно?

Решение

Предпочитаете переменные экземпляра по поводу переменных классов, если по какой-либо другой причине, чем эти классы, использующие переменные классов, немного больше боли для тестирования единиц.

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

$symbol_table = SymbolTable.new
.

На некоторых языках классы, которые используют глобальные переменные, трудно проверить.В Ruby они не так плохо, поскольку утка, набрав, позволяет вам назначать объекты Mock для глобальных переменных перед выполнением теста объекта.

или, вы можете использовать синглтон.Ruby поставляется с библиотекой, чтобы сделать это легко:

require 'singleton'
class SymbolTable
  include Singleton
  ...
end
.

Чтобы получить один и единственный экземпляр Symboltable, создал его при необходимости:

SymbolTable.instance
.

Другие советы

Используйте переменные экземпляра.Но не только (по крайней мере, не только) по причинам обработки тестов.Скорее потому, что

    .
  • каждый процесс анализа даст свой собственный символ таблицы, поэтому у вас может быть более одного за раз
  • таблица символов нужна только до тех пор, пока процесс анализа находится в диапазоне
  • Переменные классов Вводят необходимость сделать синхронизацию для достижения безопасности потоков - хотя каждый процесс анализа может отлично жить с собственным набором символов

    Приветствия

    Роберт

Просто быстрое разъяснение пару ответов, данных Роберт и Уэйн, оба из которых упоминаются переменные классов .

Оригинальный вопрос не предлагает использовать переменные классов вообще, но спрашивает использование переменных экземпляров класса .Первый выбор Hunter был использован сам объект класса в качестве единственного экземпляра таблицы символов (с состоянием, хранящимся в переменных класса экземпляра), когда вторая опция используется более типичный класс / экземплярный каркас с состоянием, хранящимся в экземпляре символаТаблица.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top