Pergunta

Eu estou construindo um analisador léxico em Ruby e estou prestes a começar a reunir e armazenar símbolos na tabela de símbolos.A minha principal questão sobre o desenho do símbolo e como se deve ser estático tabela (o que significa que todos os dados serão mantidos no nível de classe) ou se deve ser uma instância para a instância de base.

Opção 1:Classe nível da estrutura de dados

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

Com este esquema, a classe SymbolTable tem uma espécie de 'estático', funcionalidade, o que significa que eu realmente não criar uma instância de um SymbolTable, o único objeto que existe é a classe de nível.

(Suponha que SymbolTableEntry é um objeto válido, mesmo que eu não definir aqui)

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

Opção 2:Exemplo de nível de estrutura de dados

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

Com esse esquema que eu seria realmente necessário criar uma instância da classe SymbolTable para adicionar valores para a tabela de símbolos.

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

Eu gostaria de ouvir qualquer e todas as entradas em que projeto você gostaria de usar ou se preferir utilizar, bem como quaisquer comentários sobre o código de ruby em geral.

Obrigado

Foi útil?

Solução

Preferem variáveis de instância sobre variáveis de classe, se por nenhuma outra razão do que classes usando variáveis de classe são um pouco mais de dor para o teste de unidade.

Você pode usar variáveis de instância e de ainda ter uma tabela de símbolos para a todos governar.Uma maneira é através da atribuição de sua tabela de símbolos para uma variável global:

$symbol_table = SymbolTable.new

Em alguns idiomas, classes que usam variáveis globais são difíceis de testar.Em Ruby, eles não são tão ruim, uma vez que duck typing permite atribuir objetos mock para variáveis globais antes de executar o objeto sob teste.

Ou, você pode usar o padrão singleton.Ruby vem com uma biblioteca para fazer isso fácil:

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

Para recuperar a uma instância do SymbolTable, criou-o, se necessário:

SymbolTable.instance

Outras dicas

Use variáveis de instância.Mas não (pelo menos não apenas) por razões de teste de manipulação.Sim porque

  • cada analisar o processo de produzir a sua própria tabela de símbolos, de modo que você pode ter mais de um de cada vez
  • a tabela de símbolos é apenas necessário, desde como funciona o processo de análise é sob a forma
  • variáveis de classe introduzir a necessidade de fazer a sincronização para alcançar o thread de segurança - mesmo que analisar cada processo pode viver perfeitamente bem com o seu próprio conjunto de símbolos

Cheers

robert

Basta uma rápida clarificação de algumas das respostas dadas por Robert e Wayne, tanto que menciona variáveis de classe.

A pergunta original não propõem usar variáveis de classe em tudo, mas não perguntar sobre o uso de classe de variáveis de instância.A primeira escolha Hunter apresentou usada a classe de objeto em si como a única instância da tabela de símbolos (com o estado armazenado na classe de variáveis de instância), enquanto a segunda opção mais típico de classe/instância do framework com o estado armazenado em uma instância da tabela de símbolos.

Ruby variáveis de classe não são a mesma coisa que a classe de variáveis de instância e deve ser evitada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top