Символьный дизайн и внедрение таблицы в Ruby
-
14-11-2019 - |
Вопрос
Я строю лексико-анализатор в Ruby и собираюсь начать собираться и хранить символы в таблице символов. Мой главный вопрос о дизайне символа и относительно того, должен ли оно статическую таблицу (что означает, что все данные будут проводиться на уровне класса) или должны быть ли он на экземпляре.
.
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
.
.
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 - не то же самое, что и переменные экземпляра класса, и обычно следует избегать.