martes, 30 de julio de 2013

Primeros pasos

El primer paso

Como puede observarse, nuestro fichero comienza incluyendo al de la clase HTMLParser. Y es que no vamos a repetir otra vez todo lo que hicimos ahí. Otra cosa buena de la programación orientada a objetos: poder reutilizar nuestro código.

Comencemos por el constructor de la clase:

def initialize(html=nil)
  # HTML Document tags (array of HTMLThing objects)
  @nodes = html == nil ? [] : HTMLParser.new.parseHTML(html)

  # All objects created from a document share the @nodes attribute

  # Type (:document, :deleted, :node)
  @type = :document

  # Starting and ending indexes in @nodes for current object
  @starts_at = 0
  @ends_at = @nodes.length - 1


  # Pointer to Document the current object was generated from
  @document = nil

  # For :document objects, an array of objects created from it
  @nodes_created = []
end

Poco nuevo por aquí. Utilizamos un HTMLParser para analizar el código HTML que nos pasan como argumento e inicializamos las variables del objeto con unos valores razonables. A ver qué podemos hacer ahora con esto.

Una cosa interesante sería poder saber cuando nos dan un objeto de esta clase es saber si se trata de un documento, de un elemento eliminado, de si representa una etiqueta HTML, un nodo de texto, etc. Recordaréis que las clases para estos últimos tipos de objetos HTML las definimos en su día en el fichero “htmlthings.rb”.

¡Dicho y hecho! Aquí está el método que lo hace:

def typeOf
return (@type == :document or @type == :deleted) ? @type :
@nodes[@starts_at].class.name.to_sym
end

Las construcciones del tipo

Condición ? Expresión_1 : Expresión_2

… vienen a significar: “Si Condición_1 es cierto, evalúa Expresión_1. En caso contrario, evalúa Expresión_2”. Algo así como el “IF inmediato” de algunos lenguajes.

De modo que para los :document y los :deleted se devuelve su tipo. Para los :node, hay que mirar en qué posición del array de nodos comienza el contenido del objeto. Ése elemento es el que en realidad nos indica qué tenemos entre manos.

Con “.class.name.to_sym” tomamos el nombre de la clase del objeto y lo convertimos en un Symbol. ¡Y listos!

O casi listos. Porque si tenemos una etiqueta HTML quizá necesitemos saber su tipo: si es una “IMG”, un “DIV”, una “LI”, etc. Pero eso es fácil de resolver con otro método:

 
def tagName
  if typeOf != :HTMLTag
   raise 'Not a tag'
  end


  return @nodes[@starts_at].name.downcase
end

Y si queremos obtener un hash con sus atributos tampoco lo tenemos mucho más difícil:

def attributes
  if typeOf != :HTMLTag
   raise 'Not a tag'
  end


  return @nodes[@starts_at].attributes
end

No hay comentarios:

Publicar un comentario