【问题标题】:Loop through variables in different classes to match string in Ruby循环遍历不同类中的变量以匹配 Ruby 中的字符串
【发布时间】:2017-02-12 23:13:53
【问题描述】:

我有一个正在开发的 ruby​​ (sinatra) 应用程序,我的输入是一个 url 以及是否冗长(真或假),所以基本上是这样的:

网址如下所示:例如http://localhost:4567/git.company.com&v=false

获取这些的代码是这样的:

get '/:url' do |tool_url|
    url = params[:url].to_s
    is_verbose = params[:v].to_s

我在不同的文件中分隔了不同的类,我将它们包含在我的主脚本中,如下所示:

Dir["#{File.dirname(__FILE__)}/lib/*.rb"].each { |f| require(f) }

(示例文件是这样的),gitlab.rb:

class Gitlab
  $gitlab_token = 'TOKEN_GOES_HERE'
  def initialize(url, v)
    @@regex =~ /git.company.com/
    @@gitlab_url = url
    @@is_verbose = v
  end

  def check_gitlab(gitlab_url, is_verbose)
    _gitlab_overall = '/health_check.json?token=#{gitlab_token}'
    _gitlab_cache = '/health_check/cache.json?token=#{gitlab_token}'
    _gitlab_database = '/health_check/database.json?token=#{gitlab_token}'
    _gitlab_migrations = '/health_check/migrations.json?token=#{gitlab_token}'
    unless is_verbose = true
      CheckString.check_string_from_page('https://' + gitlab_url + gitlab_overall, 'success')
    else

    end
  end
end

现在,我希望能够根据用户输入的 URL 动态地知道使用哪个“类”来完成某项工作,所以我的想法是遍历这些类以查找要匹配的特定变量与输入。

我需要这方面的指导,因为我已经坚持了很长一段时间了;我已经尝试了很多我能想到的东西,但没有一个奏效。

免责声明:这里请多多包涵,因为我对 Ruby 很陌生,而且我在 OOP 语言方面也不是很出色(实际上并没有太多地练习它们)。

编辑:我愿意接受任何建议,比如如果有比这更好的不同逻辑,请告诉我。

【问题讨论】:

    标签: ruby class oop sinatra


    【解决方案1】:

    做一个哈希{ Regexp ⇒ Class }:

    HASH = {
      /git.company.com/ => Gitlab,
      /github.com/ => Github
    }
    

    然后做:

    handler = HASH.detect { |k, _| k =~ url }.last.new
    

    以上将为您提供所需类的实例。

    旁注:

    • is_verbose = params[:v].to_s 总是导致 is_verbose 设置为 truthy 值,检查 params[:v].to_s == "true"
    • is_verbose = true 是一个作业,您只想使用 unless is_verbose

    要使其运行时解析,请强制插件使用 a) include Plugin 和 b) 声明 resolve 方法。 Plugin 模块应该定义一个回调钩子:

    module Plugin
      def self.included(base)
        Registry::HASH[-> { base.resolve }] = base
      end
    end
    

    resolve 方法应该返回一个正则表达式,这里的 lambda 是为了让它在解析阶段被解析:

    class PluginImpl
      include Plugin
      def resolve
        /git.company.com/
      end
    end
    

    然后在需要的时候匹配:

    handler = HASH.detect { |k, _| k.() =~ url }.last.new
    

    另一种方法是使用ObjectSpace 来检测类,包括模块,或者在included 回调中声明TracePoint 上的base 以提供直接映射,但这一切都过于复杂了。

    【讨论】:

    • 我想过做一个散列.. 但问题是,我想让我的应用程序模块化.. 就像我希望编写新“模块”的人来定义什么要查找的主应用程序...所以我想创建一个对象数组或其他东西,如果主应用程序将 URL 与模块中指定的字符串/正则表达式匹配,则执行它。
    • 感谢您的更新。只是为了澄清一些事情,您能告诉我事情的进展吗?比如,module Plugin 是否像 gitlab.rb 一样进入 main.rbclass PluginImpl 进入“模块”?如果我已经在main.rb 中有module Main,那么将它包含在它下面会很好吗?请原谅那些初学者的问题,我是 Ruby 新手,我只是想更好地理解它。谢谢!
    • 嗯.. 这看起来是一个很好的答案,但对于像我这样的 Ruby 初学者来说非常复杂.. 我会将其标记为答案,但我必须努力让它发挥作用一些方法..也许数组模式会更容易一些..
    • 抱歉耽搁了:我有时确实会睡觉。 Plugin 是默认接口,它的代码可以放在路径的任何位置。在“主要”下很好。 PluginImplGitlabGithub,无论你想要什么“可插拔”。例如,HASH 常量可能驻留在您的 Main 类中。
    猜你喜欢
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多