Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何使其更面向对象?_Ruby On Rails_Oop_Architecture_Refactoring_Class Method - Fatal编程技术网

Ruby on rails 如何使其更面向对象?

Ruby on rails 如何使其更面向对象?,ruby-on-rails,oop,architecture,refactoring,class-method,Ruby On Rails,Oop,Architecture,Refactoring,Class Method,我是一个试图跟随那些在我之前的人的干巴巴的方法的人。 我知道我做错了什么——我只是不知道那是什么或者如何克服它 基本上,我的问题是如何使代码更面向对象 我有一个类播客,现在它只包含一堆类方法,这些类方法可以从web上获取各种数据 例如,这个类方法试图从他们的网站上发现播客twitter或facebook提要: def self.social_discovery(options = {}) new_podcasts_only = options[:new_podcasts_only] || f

我是一个试图跟随那些在我之前的人的干巴巴的方法的人。 我知道我做错了什么——我只是不知道那是什么或者如何克服它

基本上,我的问题是如何使代码更面向对象

我有一个类播客,现在它只包含一堆类方法,这些类方法可以从web上获取各种数据

例如,这个类方法试图从他们的网站上发现播客twitter或facebook提要:

def self.social_discovery(options = {})
  new_podcasts_only = options[:new_podcasts_only] || false
  if new_podcasts_only
    podcast = Podcast.find(:all, :select => 'id, siteurl, name', :conditions => ['created_at > ? and siteurl IS NOT ?', Time.now - 24.hours, nil])
    Podcast.podcast_logger.info("#{podcast.count}")
  else
    podcast = Podcast.find(:all, :select => 'id, siteurl, name', :conditions => ['siteurl IS NOT ?', nil])
  end

  podcast.each do | pod |
    puts "#{pod.name}"
    begin 
      # Make sure the url is readable by open-uri
      if pod.siteurl.include? 'http://'
        pod_site = pod.siteurl
      else
        pod_site = pod.siteurl.insert 0, "http://"
      end

      # Skip all of this if we're dealing with a feed
      unless pod_site.downcase =~ /.rss|.xml|libsyn/i
        pod_doc = Nokogiri.HTML(open(pod_site))
        pod_name_fragment = pod.name.split(" ")[0].to_s
        if pod_name_fragment.downcase == "the"
          pod_name_fragment = pod.name.split(" ")[1].to_s unless pod.name.split(" ")[1].to_s.nil?
        end
        doc_links = pod_doc.css('a')

        # If a social url contains part of the podcast name, grab that
        # If not, grab the first one you find within our conditions
        # Give Nokogiri some room to breathe with pessimistic exception handling
        begin
          begin         
            twitter_url = doc_links.find {|link| link['href'] =~ /twitter.com\// and link['href'].match(/#{pod_name_fragment}/i).to_s != "" unless link['href'] =~ /share|status/i}.attribute('href').to_s 
          rescue Exception => ex
            if doc_links.find {|link| link['href'] =~ /twitter.com\// unless link['href'] =~ /share|status/i}.nil?
              twitter_url = nil
            else       
              twitter_url = doc_links.find {|link| link['href'] =~ /twitter.com\// unless link['href'] =~ /share|status/i}.attribute('href').to_s
            end
          end

          begin    
            facebook_url = doc_links.find {|link| link['href'] =~ /facebook.com\// and link['href'].match(/#{pod_name_fragment}/i).to_s != "" unless link['href'] =~ /share|.event/i}.attribute('href').to_s
          rescue Exception => ex
            if doc_links.find {|link| link['href'] =~ /facebook.com\// unless link['href'] =~ /share|.event/i}.nil?
              facebook_url = nil
            else       
              facebook_url = doc_links.find {|link| link['href'] =~ /facebook.com\// unless link['href'] =~ /share|.event/i}.attribute('href').to_s
            end
          end
        rescue Exception => ex
          puts "ANTISOCIAL"
        # Ensure that the urls gets saved regardless of what else happens
        ensure
          pod.update_attributes(:twitter => twitter_url, :facebook => facebook_url)            
        end

        puts "#{twitter_url}" + "#{facebook_url}"
        Podcast.podcast_logger.info("#{twitter_url}" + "#{facebook_url}")
      end
    rescue Exception => ex
      puts "FINAL EXCEPTION: #{ex.class} + #{ex.message}"
    end
  end  
end
再一次,我知道这是一个糟糕的代码。请帮我理解为什么? 我将永远欠你的债

谢谢


Harris

我在您的代码中看到的主要内容是代码重复。如果仔细观察,获取twitter url的代码和facebook url的代码几乎完全相同,除了“twitter.com”和“facebook.com”部分。我的建议是将其拉到一个单独的方法中,该方法将
doc\u links
变量以及用于查找链接的正则表达式作为参数。另外,我不太清楚你为什么要在这里做“除非…”部分:

if pod_name_fragment.downcase == "the"
  pod_name_fragment = pod.name.split(" ")[1].to_s unless pod.name.split(" ")[1].to_s.nil?
end
如果不执行行的“除非…”部分,将定义pod_name_片段,但
nil
,但如果不包含它,则如果尝试引用
pod_name_片段
,将出现异常

此外,您几乎不应该营救
异常
。改用
StandardError
。假设您的程序正在运行,您尝试用Ctrl-C取消它。这会抛出一个
SystemExit
(我对名称不是100%确定)异常,它是异常出口的子类。在大多数情况下,您会希望立即退出。我知道这对于Rails应用程序来说不太适用,但我很确定还有其他原因需要捕获SystemError


可能还有更多,找到“坏代码”的一个简单方法是查看度量。Ryan Bates在metrics()上做了一个出色的Railscast,我建议您特别关注Reek,以发现“代码气味”。检查他们关于不同事物含义的信息。

我使用的是除非,因为我稍后在方法中引用了pod\u name\u片段,不能将其设置为nil。我知道我可以检查它是否为零,但我认为差异可以忽略不计。我说的对吗?但是如果你以后再参考它,它没有定义,你会得到一个非MeerError吗?