2
votes

Comment encoder json toutes les informations disponibles dans l'objet parser?

Je suis très nouveau dans le rubis et les rails. J'essaye de sortir toutes les informations whois analysées vers la sortie json. J'ai ce qui suit:

msg = {}
for prop in Whois::Parser::PROPERTIES
  msg[prop] = parser.send(prop) if parser.respond_to?(prop)
end
render :json => msg

Sortie:

undefined method `has_attribute?'

Cependant, l'analyseur a BEAUCOUP plus d'informations disponibles .... sans tout savoir les champs disponibles, comment puis-je vider toutes les clés / valeurs dans json?

J'ai essayé:

msg = {}
for x_prop in Whois::Parser::PROPERTIES
  parser.has_attribute?(:x_prop) 
    msg[x_prop] = parser.send(x_prop) 
end
render :json => msg

Mais j'ai fini par obtenir: p>

Unable to find a parser for property `registrant_contacts'

EDIT:

J'ai aussi essayé:

class WhoisController < ApplicationController
    def index
        c = Whois::Client.new
        record = c.lookup("google.com")
        parser = record.parser
        msg = {}
        for x_prop in Whois::Parser::PROPERTIES
            msg[x_prop] = parser.send(x_prop)
        end
        render :json => msg
    end
end

Mais finit par obtenir une autre erreur:

undefined method `attributes' for #<Whois::Parser:0x00007fc030d74018>

Python et Go (par réflexion) peuvent le faire. Quelle est la manière Ruby pour y parvenir?

EDIT:

parser.attributes.each do |attr_name, attr_value|
  puts attr_name
end

Cela fonctionne UNIQUEMENT si toutes les propriétés existent sur l'analyseur. Cependant, certains noms de domaine n'ont pas toutes les propriétés et entraîneront:

SystemStackError in WhoisController#index

J'essaye alors de le définir uniquement si cette propriété existe:

class WhoisController < ApplicationController
  def index
    c = Whois::Client.new
    record = c.lookup("google.com")
    parser = record.parser
    msg = {:whois => parser}
    render :json => msg
  end
end

J'obtiens une autre erreur:

{"created":"1997-09-15T00:00:00.000-07:00"}

EDIT # 3:

J'ai aussi essayé:

class WhoisController < ApplicationController
  def index
    c = Whois::Client.new
    record = c.lookup("google.com")
    parser = record.parser
    created = parser.created_on
    msg = {:created => created}
    render :json => msg
  end
end

Cela échoue toujours si la propriété est manquante dans l'analyseur. ; (


0 commentaires

3 Réponses :


0
votes

Pour SystemStackError dans WhoisController # index :

Je pense que c'est parce que vous appelez à nouveau whois avec Whois à record = Whois.whois ("google.com") . Essayez record = whois ("google.com") .

Pour méthode non définie `attributes 'for # : La méthode attributes ne quitte pas l'analyseur whois. Voir https://whoisrb.org/docs/v3/parser-properties/ .


3 commentaires

Whois.whois est valide ... aussi whois.lookup est également valide. Je mixais et assortis. J'ai édité les échantillons.


donc, il n'y a aucun moyen de parcourir tous les champs? En python et allez-y, il existe des moyens de le faire.


@MarissaLevy Je ne dirais pas qu'il n'y a aucun moyen. Mais vous devrez écrire vous-même la boucle pour parcourir les propriétés de l'analyseur. Parfois, certaines bibliothèques présentent des différences mineures entre les fonctions / méthodes qu'elles fournissent pour plusieurs langues.



-2
votes

Vous pouvez utiliser les méthodes ou inspect.

    render json: parser.inspect.to_json
    c = Whois::Client.new
    record = c.lookup("google.com")
    parser = record.parser
    render json: parser.methods.to_json


0 commentaires

2
votes
begin
    msg[x_prop] = parser.send(x_prop)
rescue
    # do nothing
end

7 commentaires

Sur certains d'entre eux, j'obtiens "Impossible de trouver un analyseur pour la propriété` registrant_contacts '"


parser.has_attribute? (: prop) msg ​​[prop] = parser.send (prop) J'obtiens la méthode non définie `has_attribute? '


@MarissaLevy utilise simplement une capture d'essai, comme ma modification sur réponse


merci pour aider un newb .... une autre prime à venir quand je suis autorisé à le récompenser.


La question ici est: Pourquoi utiliser une boucle for alors que vous pouvez utiliser #each ? Ou #each_with_object d'ailleurs.


for ... in est très unidiomatique pour Ruby. Ce n'est pas faux, mais l'utilisation d'itérateurs tels que la suggestion de @ JohanWentholt conduit généralement à un code plus concis et compréhensible. En outre, la vérification de la capacité à effectuer une tâche ( if..else..end ) est généralement plus performante au point que le sauvetage. Rescue est mieux utilisé pour intercepter les exceptions , ce qui est inattendu, et non pour gérer les échecs attendus.


L'autre problème avec for ... in est qu'il ne crée pas de nouvelle portée. Toutes les variables définies dans la portée (y compris x_prop ) sont toujours disponibles après l'itération. Cela peut parfois conduire à un comportement inattendu. Alors que l'utilisation d'un itérateur ajoutera une nouvelle portée sur la portée actuelle, vous permettant d'observer des variables externes ou de définir des variables qui ne sont disponibles que lors de l'itération. Dans certains cas, vous voudrez peut-être utiliser for ... in , mais en général si vous n'avez pas de raison valable d'utiliser #each .