0

私は宝石に取り組んでいます。これがそのホームページです: https://github.com/scaryguy/vakit

ソース コードを確認すると、外部の HTML ページを解析してデータをフィルター処理していることがわかります。

問題は、1 つの要求で必要なすべてのデータをフェッチしても、呼び出すたびに、Vakit.sabahまたはVakit.oglen新しい要求が行われることです。

require "vakit/version"
require 'vakit/connect'
require 'Nokogiri'
require 'open-uri'

module Vakit

  def self.today
    Vakit::Connect.shaber
  end

  def self.imsak
    Vakit::Connect.shaber[:imsak]
  end

  def self.sabah
    Vakit::Connect.shaber[:sabah]
  end

  def self.oglen
    Vakit::Connect.shaber[:oglen]
  end

  def self.ikindi
    Vakit::Connect.shaber[:ikindi]
  end

  def self.aksam
    Vakit::Connect.shaber[:aksam]
  end

  def self.yatsi
    Vakit::Connect.shaber[:yatsi]
  end

end

効率の良い方法とは思えません。

新しいリクエストなしでハッシュの属性にアクセスできるはずですよね?

module Vakit
class Connect
    def initialize(opt={})
        @path = opt[:path]
    end

    def self.shaber
        doc = Nokogiri::HTML(open('http://www.samanyoluhaber.com/'))
        x = doc.css('#hnmzT')

        times = []
        x.each do |vakit|
            data = vakit.children.first.children.last.content
            data_add = data.slice(0..data.length-2)
            times.push(data_add)
        end
        times
        vakit = {

            imsak: times[0],
            sabah: times[1],
            oglen: times[2],
            ikindi: times[3],
            aksam: times[4],
            yatsi: times[5]


        }

    end

end
end

私はいくつかの啓蒙が必要です。

4

3 に答える 3

1

shaberyou を明示的に使用openしてコンテンツを再解析するたびに。コンテンツまたは解析された DOM をローカルに保存して、既に持っているかどうかを確認しようとしているわけではありません。

doc =使用する代わりに@@doc ||=、 の出現箇所を に変更doc@@docます。

演算子は、が空の||=場合にのみ割り当てます。@@docnil 以外または false 以外の値に割り当てられると、再度トリガーされることはないため、貧弱な「メモ化」です。

クラスメソッドを使用しているため、クラス変数の使用をお勧めします。異なるページを見ているクラスのインスタンスが複数ある場合は、代わりに@@docインスタンス変数になる可能性があります。@docそのままでは、1 ページのみをハードコーディングしたため、違いはありませんが、将来のコードの成長のために役立つ可能性があります。


ページにアクセスするために作成したコードは、あまり慣用的な Ruby ではありません。次のように書きますが、URL が十分な時間値を持つページを返していないため、うまくいきません。

require 'nokogiri'
require 'open-uri'

module Vakit

  URL = 'http://www.samanyoluhaber.com/'

  class Connect
    def initialize(opt={})
      @path = opt[:path]
      @url = opt[:url] || URL
    end

    def shaber(url=nil)
      doc = Nokogiri::HTML(open(url || @url))
      doc.at_css('#hnmzT').to_html # => "<li id=\"hnmzT\" name=\"imsak\"><a id=\"at\"><span>\u0130msak:</span>4:22\u00A0</a></li>"

      x = doc.at_css('li#hnmzT a')
      x.to_html # => "<a id=\"at\"><span>\u0130msak:</span>4:22\u00A0</a>"

      times = x.text.scan(/\d+:\d+/)

      Hash[[:imsak, :sabah, :oglen, :ikindi, :aksam, :yatsi].zip(times)]
    end

  end
end

connection = Vakit::Connect.new
connection.shaber # => {:imsak=>"4:22", :sabah=>nil, :oglen=>nil, :ikindi=>nil, :aksam=>nil, :yatsi=>nil}

Connectクラスの名前としては適切ではありません。クラスはオブジェクト、モノです。Connect動詞であり、物事に対して発生する、または発生するものです。connectメソッドの良い名前です。

于 2013-08-11T14:10:15.770 に答える
0

この行 doc = Nokogiri::HTML(open('http://www.samanyoluhaber.com/'))は、要求された呼び出しを数回行っているものです。

私はあなたの宝石でこれをテストしましたが、これはうまくいくようです。

if @doc.nil?
  @doc = Nokogiri::HTML(open('http://www.samanyoluhaber.com/'))
end

さらにvakit.rbの変更

require 'Nokogiri' to require 'nokogiri'(単純なn)

于 2013-08-11T14:07:02.247 に答える
0

次の提案をします。

  1. Vakit::Connectクラス内のインスタンス メソッドである必要があります。そのため、インスタンス化してメモリに保存できます。このようにして、各リクエストは同じオブジェクトの異なるインスタンスになります。クラスが存在しない場合。作成してください。
  2. memorizationコストのかかる操作をキャッシュするために使用します。
  3. 操作に時間がかかる場合は、3 秒以上とします。それをバックグラウンドジョブに変換し、ワーカーを使用してそれらを処理します。ただし、gem を作成しているためです。この責任は、gem を使用する開発者に委任する必要があると思います。

だから私はそれを次のようにします:接続クラス:

module Vakit
class Connect
attr_accessor :path, :doc
def initialize(opt={}, url)
  @path = opt[:path]
  @doc = Nokogiri::HTML(open(url))
end

def shaber
 x = @doc.css('#hnmzT')
  #no changes here
end
end

Vakit モジュール

module Vakit
 class Main #name it something more meaningful   
  def initialize(opt={})
   @connected = Connect.new(opt[:path], 'http://www.samanyoluhaber.com/')
  end
  def today
   @connected.shaber
  end

  def imsak
   today[:imsak]
  end

  def sabah
   today[:sabah]
  end

  def oglen
   today[:oglen]
  end

  def ikindi
   today[:ikindi]
  end

  def aksam
   today[:aksam]
  end

  def yatsi
   today[:yatsi]
  end

end

コードでは、次のように使用できます。

@v = Vakit::Main.new
@v.aksam

私はあなたのコードの目的を本当に理解していないので、これは 100% 完璧ではないかもしれません。ただし、ハッシュにアクセスするたびに新しいリクエストが作成されるわけではありません。

于 2013-08-11T14:10:07.923 に答える