在另一个Ruby方法中访问局部变量



我希望了解如何访问方法a中的变量集,然后在方法B中使用该变量,以及重用相同部分代码的干净方式,然后仅更改查询

require 'google/api_client'
module GoogleAnalytics
 class Analytic
 SERVICE_ACCOUNT_EMAIL_ADDRESS = ENV['SERVICE_ACCOUNT_EMAIL_ADDRESS']
 PATH_TO_KEY_FILE              = ENV['PATH_TO_KEY_FILE']
 PROFILE                       = ENV['ANALYTICS_PROFILE_ID']
def google_analytics_api
client  = Google::APIClient.new(
  application_name: "Example Application",
  application_version: "1.0")
client.authorization = Signet::OAuth2::Client.new(
  :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
  :audience             => 'https://accounts.google.com/o/oauth2/token',
  :scope                => 'https://www.googleapis.com/auth/analytics.readonly',
  :issuer               => SERVICE_ACCOUNT_EMAIL_ADDRESS,
  :signing_key          => Google::APIClient::KeyUtils.load_from_pkcs12(PATH_TO_KEY_FILE, 'notasecret')).tap { |auth| auth.fetch_access_token! }
  api_method = client.discovered_api('analytics','v3').data.ga.get

  # make queries
  result = client.execute(:api_method => api_method, :parameters => {
  'ids'        => PROFILE,
  'start-date' => Date.new(2014,1,1).to_s,
  'end-date'   => Date.today.to_s,
  'dimensions' => 'ga:pagePath',
  'metrics'    => 'ga:pageviews',
  'filters'    => 'ga:pagePath==/'
 })
  end
 end
end

因此,如果我运行google_analytics_api方法,我将获得一组返回的结果,分配给变量result

那么如果我想要另外两个独立的方法,将返回不同的结果集,那么新用户和跳出率,这将是两个单独的调用改变请求参数,不是吗?我需要重复整个方法吗?

是否有一种方法可以重构它,以便授权调用可以被包装在它的on方法中,而所有的更改都是分配给result的请求参数?

所以像这样的

def api_call
  logic to make request
end
def new_users
  api_call
   # make queries
  result = client.execute(:api_method => api_method, :parameters => {
  'ids'        => PROFILE,
  'start-date' => Date.new(2014,1,1).to_s,
  'end-date'   => Date.today.to_s,
  'dimensions' => 'ga:pagePath',
  'metrics'    => 'ga:newUsers',
  'filters'    => 'ga:pagePath==/'
 })

end
其中一个问题是,在new_users方法中可以使用局部变量clientresult,这些可以更改为什么?带有@的实例变量?或者一个带有@@ ?
的类变量

您的直觉很好—您不想重复自己,并且有更好的方法来构建此代码。但是,与其共享变量,不如考虑小块、松散连接的。编写能很好地完成一件事的方法,并将它们组合在一起。例如,我们可以编写一个get_client方法,它只返回一个client供其他方法使用:

protected
def get_client
  client  = Google::APIClient.new(
    application_name: "Example Application",
    application_version: "1.0")
  client.authorization = Signet::OAuth2::Client.new(
    :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
    :audience             => 'https://accounts.google.com/o/oauth2/token',
    :scope                => 'https://www.googleapis.com/auth/analytics.readonly',
    :issuer               => SERVICE_ACCOUNT_EMAIL_ADDRESS,
    :signing_key          => Google::APIClient::KeyUtils.load_from_pkcs12(PATH_TO_KEY_FILE, 'notasecret')).tap { |auth| auth.fetch_access_token! }
  client
end

它是protected,因为外部代码-你的Analytic类之外的东西-不应该与它直接工作。他们应该使用我们提供给他们的方法。


您还可以提供一个从API获取结果的助手方法。我不熟悉查询API,但看起来这是你的metrics值的变化。比如像这样:

protected
def get_result(metrics)
  client = self.get_client
  api_method = client.discovered_api('analytics','v3').data.ga.get
  result = client.execute(:api_method => api_method, :parameters => {
    'ids'        => PROFILE,
    'start-date' => Date.new(2014,1,1).to_s,
    'end-date'   => Date.today.to_s,
    'dimensions' => 'ga:pagePath',
    'metrics'    => metrics,
    'filters'    => 'ga:pagePath==/'
   })
  result
end

现在你可以编写简单的方法,你的外部类可以使用:

def new_users
  get_result('ga:newUsers')
end
def total_visits
  get_result('ga:pageViews')
end

如果可以,尝试从这些方法返回简单的数据。也许total_visits会返回get_result('ga:pageViews')['totalsForAllResults']['ga:pageviews']。类之外的代码不需要知道GA数据格式才能使用它。

通过Skype聊天,我认为有几件事值得关注


Init

当前,每次要使用该模块时都使用google_analytics_api方法。这是完全没有效率的,也是现在出现这个问题的部分原因。相反,我将创建一个init方法,它将在每次初始化对象时触发(并使GoogleAnalytics成为它自己的类):

#lib/google_analytics.rb
Class GoogleAnalytics
   def initialize
       ... google_analytics_api method here
   end
end

这将允许你把你的当前模块当作一个真正的Ruby对象——像这样:

@analytics = GoogleAnalytics.new #-> fires initialize method

这将使您能够调用对象(它将从API中提取数据),然后根据您拥有的不同用例相应地拆分该数据。


实例方法

这让我想到了实例方法

你所指的,实际上是Alex P所指的,是一个实例方法的概念。这可以作为对象的属性,但实际上允许您在方法的实例上调用一段功能。

在Alex的例子中,你有:

def new_users
  get_result('ga:newUsers')
end

这只是调用类的instance方法:

GoogleAnalytics::Analytic.new_users

这将创建Analytic类的实例,然后调用new_users方法(应该是class method)。这个方法将允许你在新初始化的对象上调用instance方法,因此get_result方法调用

,

我建议的是在对象初始化后使用instance methods ,让您访问用google_analytics_api

定义的数据例如:

#app/controllers/analyics_controller.rb
Class AnalyticsController < ApplicationController
   def index
       @analytics = GoogleAnalytics.new
       @new_users = @analytics.new_users
   end
end
#lib/google_analytics.rb
Class GoogleAnalytics
   def initialize
       ... google_analytics_api method here
   end
   def new_users
      return [new_users_data]
   end
end

需要注意的是,如果没有模块,这是否可以工作。我想应该可以,但是我还没有测试过

相关内容

  • 没有找到相关文章

最新更新