如何在Ruby中检测方法链的结尾 [英] How to detect the end of a method chain in Ruby

查看:76
本文介绍了如何在Ruby中检测方法链的结尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Flickr界面,我之前写过,它的一部分困扰着我,我想让它变得更好.它的工作方式是我使用缺少的方法来从flickr对象上调用的方法构造flickr调用的url参数,例如.

I have a Flickr interface that I wrote a while ago and part of it bothers me and I'd like to make it nicer. The way it works is I use method missing to construct the url parameters for the flickr call from the methods called on the flickr object, eg.

@flickr.groups.pools.getPhotos(:user_id => "12656878@N06", :group_id => "99404851@N00")

这些方法调用"构造了一个如下所示的api调用

These 'method calls' construct an api call that looks like this

http://api.flickr.com/services/rest/?method=groups.pools.getPhotos&user_id=1848466274& group_id= 99404851@N00

(我放弃了api密钥位) 为此,它会记住每个方法",直到使用实参调用方法为止,然后构造URL并调用Flickr.

(I have left off the api key bit) It does this by remembering each 'method' until a method is called with arguments at which time it constructs the url and and makes the call to Flickr.

我采用这种方法的原因是,ruby代码与Flickr网站上的文档相匹配,您可以复制并粘贴它,并且大多数情况下都可以使用,并且希望它将使它对api的更改更具弹性,因为我有没有硬编码的方法.

The reason I took this approach is so the ruby code matches the documentation on the Flickr site, you can copy and paste it and it will mostly work, and hopefully it will make it a bit more resilient to api changes because I have no hard coded methods.

尽管如此,但令人烦恼的是,在此示例中,组标识被传递给getPhotos方法,而不是组方法.我更希望它看起来像这样.

What irritates about this though is that in this example the group id is being passed to the getPhotos method rather than the groups method. I would much rather it looked like this.

@flickr.groups(:group_id => "99404851@N00").pools.getPhotos(:user_id => "12656878@N06")

所以我的问题. Ruby中有什么方法可以检测到最后一个方法已被调用,从而可以触发对Flickr的调用?

So my question. Is there any way in Ruby that I can detect that the last method has been called so that I can trigger the call to Flickr?

推荐答案

由于我无法想到检测上一个方法调用的任何方法,因此我将建议使用另一种方法.它类似于ActiveRecord的功能.代理类,可构建选项并且在调用调用对数据进行操作的方法之前不会获取数据.

Since I can't think of any way to detect the last method call, I'm going to suggest a different approach. It is similar to what ActiveRecord does; a proxy class that builds the options and doesn't fetch the data until you call a method that operates on the data.

class Flickr
  def initialize
    @result = FlickrResult.new
  end

  def method_missing(method, *args, &block)
    if @result.data.respond_to?(method)
      @result.run(method, args, block)
    else
      @result.append(method, args[0])
      return self
    end
  end

  class FlickrResult
    attr_reader :data

    def initialize
      @data = []
      @keys = []
      @options = {}
    end

    def append(key, options)
      @keys << key
      @options.merge!(options) if options
    end

    def run(method, args, block)
      if !@did_run
        fetch_data
      end

      @data.send(method, *args, &block)
    end

    def fetch_data
      puts "Only runs once!"
      @url = @keys.join(".") + "?" + @options.map {|k, v| "#{k}=#{v}" }.join("&")
      # use @url and fetch data..
      @data = ["foo", "bar"]

      @did_run = true
    end
  end
end

@flickr = Flickr.new
@flickr.groups(:group_id => "123").pools.thing.users(:user_id => "456")

@flickr.each {|f| p f }
# => "Only runs once!"
# => "foo"
# => "bar"
p @flickr.map {|f| f.upcase }
# => ["FOO", "BAR"]

仅当您eachmap或任何数据(任何数组方法)时才获取数据.

It only fetches the data when you each or map it or whatever (any array method).

这篇关于如何在Ruby中检测方法链的结尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆