Ruby中的产量以及块的工作原理

时间:2011-12-28 11:22:30

标签: ruby

我是新来的,我希望我会回答我的问题。 我有三节课。

  1. 转轮
  2. 作家
  3. 公司
  4. 在跑步者课上我有

    writer = Writer.new(directory + datasource.downcase + ".xml")
    ds = ("Sitemap::" + datasource).constantize.new(country_version, directory, country_host)
    writer.fill do
                ds.yield_data {|entry| writer.write_entry(entry)}
    end
    

    Yeild_data在班级公司

    write_entry在Writer类

    以下是公司代码类

      class Company
    
        def initialize(country_version, directory, country_host)
          @country_version = country_version
          @directory = directory
          @country_host = country_host
        end
    
        def yield_data
          ::Company.find_each(:conditions => {:country_version_id => @country_version.id}) do |company|
           output = yield entry(company)
           puts output
          end
        end
    
        private
        def entry(company)
          {
            :url => ActionController::Integration::Session.new.url_for(:controller => 'companies', :action => 'show', :company_name => company.name, :host => @country_host.value),
            :frequency => 0.8,
            :priority => 'monthly',
            :lastmod => company.updated_at
          }
        end
      end
    

    以下是班级作家

     class Writer
        include ActionController::UrlWriter
    
        def initialize(filepath)
          @filepath = RAILS_ROOT + filepath
          @xml_document = Nokogiri::XML::Document.new
        end
    
        def fill
          File.open(@filepath,"w") do |f|
            f.write(%[<?xml version="1.0" encoding="UTF-8"?>\n])
            f.write(%[<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n])
            yield self
            f.write(%[</urlset>])
            f.close
          end
        end
    
        def write_entry(entry)
          node = Nokogiri::XML::Node.new("url", @xml_document)
          node["loc"]= entry[:url]
          node["lastmod"]= entry[:lastmod].to_s
          node["changefreq"] =  entry[:frequency].to_s
          node["priority"] = entry[:priority].to_s
          node.to_xml
          #@filepath.write(node)
        end
      end
    

    请回答我以下问题:

    1. 什么将进入(公司)返回(公司类)
    2. 什么会产生自我回报(在作家班级)
    3. 如何将节点写入xml文件

1 个答案:

答案 0 :(得分:0)

看看你的范围。请记住,隐含self

  1. 我们在一个实例方法中,它产生self.entry(company)。因此它会在当前实例上返回对entry(company)的调用输出(在您发布的第一个代码中似乎是ds

  2. 仍然是一个实例方法,因此它将返回self,也就是调用了Writer的实例化fill,即您的writer对象第一个代码

  3. 正如@Frederick所说,你应该在另一个问题中询问XML,并保持你的问题简明扼要。请阅读FAQ以了解有关如何使用此网站的更多信息。欢迎来到社区!

  4. 编辑:对块的一些帮助

    块有点像匿名函数。

    每当你这样做时:

    some_method {|block_args| some_block }
    

    想象一下你将函数传递给some_method,该函数需要block_args。现在你做的时候:

    def some_method
      yield some_args
    end
    

    想象一下你用block_args = some_args来调用该块。想象一个像简化方法签名的块一样,没有方法名,但有一个参数列表。事实上,这就像在做:

     def some_method
       my_block( some_args )
     end
    
     def my_block( block_args )  
       # do something and return the result
     end
    

    有一个值得注意的例外,即块被绑定到调用它的上下文:

     class Myclass
       def hi
         # we are in an instance method, so self = the instance on which it is called
         OtherClass.new.hello { self.name }
       end
    
       def name
         "world"
       end
     end
    
     class OtherClass
       def hello
         puts "hello #{ yield } !" # here, we call the block without args
       end
     end
    
     # self.name is evaluated in the context it is called, so :
     >> Myclass.new.hi
     "hello world !"
     => nil
    

    现在想象一下yield是一个代表块的函数名;如果块返回某些内容,则可以将其用作任何其他函数的返回值。一个小例子,其中包含现有Enumerable#map方法的虚拟实现:

     def map
       result = []
       self.each do |element|
         result << yield element # store in an array the result of the block for each element...
       end
       result                    # and return it
     end
    
    >> [1,2,3].map {|e| e * e }
    => [1,4,9]