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
@nodes[@starts_at].class.name.to_symreturn (@type == :document or @type == :deleted) ? @type : 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 |