繁体   English   中英

在另一种方法Ruby中访问Local变量

[英]Access Local variable in another method 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

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

有没有一种方法可以重构它,以便可以将授权调用包装在其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,我认为有几件事要看


在里面

当前,每次要使用该模块时,您都在使用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

需要注意的一个问题是,如果没有该模块,这是否可以工作。 我认为应该,但是未经我测试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM