简体   繁体   English

将块中目录中的所有ruby文件作为内联代码包含在内

[英]Include all the ruby files from a directory inside a block as inline code

Structure of ruby file is as shown below, 红宝石文件的结构如下图所示,

market
  |__abcd
       |__classification
              |__for_sale_mobile_phone.rb
              |__catalogues
                  |__mobile_phone_brands
                      |__acer.rb
                      |__apple.rb
                      |__samsung.rb

In for_sale_mobile_phone.rb , I like to include all brands of mobile_phone_brands under a block. for_sale_mobile_phone.rb ,我希望将所有品牌的mobile_phone_brands在一个mobile_phone_brands下。

I m trying to include brands in below fashion, 我正在尝试以不流行的方式加入品牌,

 .....
    c.tree_field :brand, { child_key: :model } do |b|
      Dir[
        File.dirname(__FILE__) + '/catalogues/mobile_phone_brands/*.rb'
      ].each { |brand| load brand }

      b.required = true
    end
.....

here is how brand file looks like. 这是品牌文件的外观。 for example, apple.rb 例如apple.rb

b.value "apple" do |brand|
  brand.value "6plus"
  brand.value "6s"
  brand.value "6s-plus"
  brand.value "se"
  brand.value "7"
  brand.value "7-plus"
  brand.value "other-model"
end

I m getting below error, 我低于错误,

undefined local variable or method `b' on line 1: apple.rb

How can I include file under a block scope? 如何在阻止范围内包含文件?

Thanks in advance! 提前致谢!

You should separate file "loading" from function execution. 您应该将文件“加载”与函数执行分开。 Redefine your file like this. 像这样重新定义您的文件。

class AppleLoader

  def self.load(b)
    b.value "apple" do |brand|
      brand.value "6plus"
      brand.value "6s"
      brand.value "6s-plus"
      brand.value "se"
      brand.value "7"
      brand.value "7-plus"
      brand.value "other-model"
    end
  end
end

On top of file you load required classes like this: 在文件顶部,您可以加载所需的类,如下所示:

require '/catalogues/mobile_phone_brands/apple_loader.rb'

And when you want to load Apple brand in the b object: 当您要在b对象中加载Apple品牌时:

AppleLoader.load b

Better Approach: To me it feels like Apple.rb defers from Samsung.rb only in terms of data. 更好的方法:在我看来, Apple.rb只是从数据方面推迟了Samsung.rb If that's the case, and functionality for both of them are same then I would rather: 如果真是这样,并且两者的功能都相同,那么我宁愿:

  1. put that data in a Yaml file( brands.yml ) instead of rb file. 将该数据放在Yaml文件( brands.yml )中,而不是rb文件中。

      brands: apple: ["6plus", "6s"] samsung: ["galaxy"] 
  2. Have just one common loader called BrandLoader 只有一个常见的装载机,称为BrandLoader

     class BrandLoader def self.load(b, brand_name, values) b.value brand_name do |brand| brand_values.each do |value| brand.value value end end end end 
  3. Iterate over brands by reading Yaml 阅读Yaml遍历品牌

     configurations = YAML.load "brands.yml" configurations["brands"].each do |brand_name, values| BrandLoader.load(b, brand_name, values) end 

The way I figured out is by using eval but cautious read up is-eval-supposed-to-be-nasty , eval works for me as I'm not using user input. 我发现的方法是使用eval但谨慎的阅读是eval-suppose-to-nastyeval对我有效,因为我没有使用用户输入。

To make any code in different file, execute as the code written in the place of call. 要在不同文件中编写任何代码,请执行在调用位置编写的代码。 Use eval(File.read(file_path) 使用eval(File.read(file_path)

 .....
    c.tree_field :brand, { child_key: :model } do |b|
      Dir[
        File.dirname(__FILE__) + '/catalogues/mobile_phone_brands/*.rb'
      ].each { |brand| eval(File.read(brand)) }

      b.required = true
    end
.....

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

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