Rodrigo Martins

I'm a Catholic Christian, software developer, Passionate about life, codes, questions, theories and theorems. :)

Classe Objects Em Ruby 1.9.2 - Part VI

| Comments

Hoje vamos continuar falando de Objects, é hora de nos aprofundar.

Objetos

Copiando objetos

A classe Object define dois métodos estreitamente relacionados para copiar objetos. Tanto o clone e como o dup retornar uma cópia superficial do objeto em que eles são chamados. Se o objeto copiado inclui o estado interno que se refere a outros objetos, apenas as referências a objetos são copiadas, não os próprios objetos referenciados.

Se o objecto a ser copiado define um método initialize_copy, em seguida, clone e dup simplesmente alocam uma nova instância vazia da classe e chamam o método initialize_copy nesta instância vazio. O objeto a ser copiado é passado como um argumento, para este “Construtor de cópias”, podendo inicializar a cópia. Para exemplo, o método initialize_copy pode copiar recursivamente os dados internos de um objeto para que o objeto resultante, não sendo uma simples cópia superficial do original.

Classes também podem substituir os métodos clone e dup diretamente para produzir qualquer tipo de copia que eles desejam.

Há duas diferenças importantes entre os métodos clone e dup definidos pelo objeto. Primeiro, as cópias do clone tanto o congelado e quanto o estado contaminado(definido em breve) de um objeto, enquanto dup apenas copia o estado contaminado, chamando dup sobre um objeto congelado retorna uma cópia descongelada. Em segundo lugar, clone cópia quaisquer métodos singleton do objeto, enquanto que dup não.

Objetos Empacotamento

Você pode salvar o estado de um objeto passando para a classe Marshal, com o método dump. Se você passar um objeto de fluxo de I/O como o segundo argumento, escreve o estado do objeto Marshal.dump (e, de forma recursiva, quaisquer objetos que referencia) para esse fluxo. Caso contrário, ele simplesmente retorna o estado codificado como uma string binária.

Para restaurar um objeto empacotado, passe uma string ou um fluxo de contendo I/O do objeto de Marshal.load.

O empacotamento de um objeto é uma maneira muito simples para salvar seu estado para uma utilização posterior, e estes métodos podem ser usados ​​para fornecer um arquivo automático no formato de programas Ruby. Note, no entanto, que o formato binário usado por Marshal.dump e Marshal.load é dependente da versão, e nas mais recentes versões do Ruby não são garantidos para ser capaz de ler objetos empacotados escritos por versões mais antigas do Ruby.

Outro uso para Marshal.dump e Marshal.load é criar cópias de profundidade de objetos:

Marshal
1
2
3
def deepcopy(o)
  Marshal.load (Marshal.dump (o))
end

Note que os arquivos de fluxo I/O, bem como o método e os objetos Binding, são dinâmicos demais para ser empacotado, não haveria nenhuma maneira confiável para restaurar seu Estado.

YAML (“YAML não é Markup Language”) é uma alternativa comumente utilizada para o módulo Marshal que depósita objetos (e carrega objetos) a partir de um texto com formato legível. É na biblioteca padrão, e você deve exigir usá-lo ‘yaml’.

Objetos de congelamento

Qualquer objeto pode ser congelado chamando seu método de freeze. A objeto congelado torna imutável e nenhum de seu estado interno pode ser mudado, e uma tentativa de chamar qualquer um dos seus métodos de falha de modificadores:

Freeze
1
2
3
4
5
s = "gelo" # String são objetos mutáveis
s.freeze # Faça desta cadeia imutável
s.frozen? # Verdade: ele foi congelado
s.upcase! # TypeError: não pode modificar cadeia de congelados
s[0] = "ni" # TypeError: não pode modificar cadeia de congelados

Congelar um objeto de classe impede a adição de quaisquer métodos para essa classe.

Você pode verificar se um objeto é congelado com o método frozen?. Uma vez congelado, não há maneira para “descongelar” um objeto. Se você copiar um objeto congelado com clone, a cópia também será congelada. Se você copiar um objeto congelado com dup, no entanto, a cópia não será congelada.

Objetos contaminados e não confiáveis

Aplicações Web deve muitas vezes acompanhar de dados de entrada, derivados de não confiáveis do usuário para evitar ataques de injeção de SQL e riscos de segurança semelhantes. Ruby oferece uma solução simples para esse problema: qualquer objeto pode ser marcado como contaminado, chamando seu método taint. Depois que um objeto está contaminado, qualquer objetos derivado, também será contaminado. O taint de um objeto pode ser testado com o método tainted? método:

taint
1
2
3
4
5
s = "não confiáveis" # Os objetos são normalmente não viciada
s.taint # Marcar como não confiável objeto contaminado
s.tainted? # Verdade: ele está contaminado
s.upcase.tainted? # Verdade: objetos derivados estão contaminados
s[3,4].tainted? # Verdade: substrings estão contaminados

De entrada, tais como usuário de linha de comando argumentos, ambiente de variáveis, e seqüências de leitura com gets, são automaticamente contaminados. Quando a variavel global $SAFE é definida com um valor maior que zero, Ruby restringe vários métodos embutidos que eles não vão trabalhar com dados adulterados. Cópias de objetos contaminados feitos com clone e dup permanecem contaminados. Um objeto contaminado pode ser descontaminado com o método untaint. Você só deve fazer isso, claro, se você examinar o objeto e está convencido de que não apresenta riscos de segurança.

Em Ruby 1.9, os objectos podem não ser confiável para além de ser manchado. Os métodos untrusted?, untrust, e trust verificam e definem a lealdade de um objeto. Código não confiável cria objetos não confiáveis, objetos contaminados e não é permitido para modificar objetos confiáveis.

Boa noite amigos… até a proxima..

Comments