【问题标题】:Can I create a method-scoped constant in Ruby?我可以在 Ruby 中创建一个方法范围的常量吗?
【发布时间】:2013-07-15 05:30:03
【问题描述】:

我想创建一个只能在其包含方法内访问的常量。在其他语言中,人们可能会这样做:

void function()
{
  const int MAX = 25;
  int array[MAX];

  //DO SOMETHING
}
void function2()
{
   const int MAX = 50;
   int array[MAX];
   //DO SOMETHING ELSE
}

在这两种方法中,MAX 对类来说不是全局的。我相信数据隐藏,我想知道是否有办法在 Ruby 中做到这一点。我们可以在方法中创建常量吗?

【问题讨论】:

  • 我会质疑您为什么需要这样做。当然,如果你在方法中创建它,你可以简单地在方法中创建一个你从不修改的变量?
  • 当已知值是常量时,它可以更容易地阅读代码。我看到 MAX,我知道它的常数。我看到最大值,我认为它是计算出来的。我的同事在我前往更绿色的牧场 6 个月后看到了我的代码,并且知道我的意图。
  • @baash05,有点奇怪,动态常量呢?我改进了我的答案。 ;)

标签: ruby oop constants


【解决方案1】:

不,你不能,但即使你可以,也没什么意义,因为 Ruby 中的常量并不是真正的常量:

MY_CONST = 'foo'
MY_CONST << 'bar'
MY_CONST  #=> 'foobar'
MY_CONST = 'baz' # warning: already initialized constant MY_CONST

如果您担心对象本身被修改(而不是引用,如果您返回对象更有意义),那么您可能希望freeze 对象以防止它被变异(不过请注意,这是一个浅冻结,对于深度冻结,请参阅IceNine)。

【讨论】:

    【解决方案2】:

    你不能那样做。问题不在于常量是否是私有的。 Ruby 禁止在方法定义中创建常量。

    def foo
      Foo = :foo
    end
    # => SyntaxError: ... dynamic constant assignment
    

    【讨论】:

    • 在运行时通过 class_eval 分配常量怎么样?
    • @JeslyVarghese 这是可能的。但这无济于事。
    【解决方案3】:

    有点矛盾,这个想法很奇怪,动态常量呢?

    class FOO
      def method
        method_constant :METHOD_CONSTANT, 25
        METHOD_CONSTANT
      end
      def method_constant(constant_name, value)
        constant_name.to_s.slice!(0,1) 
        FOO.class_eval "#{constant_name} = #{value}"
        FOO.class_eval "private_constant :#{constant_name}"
      end
      private :method_constant
    end
    
    f = FOO.new
    f.method #:=>25
    FOO::METHOD_CONSTANT #:=>error
    

    好吧,这些常量将在定义它的方法范围之外可用。不确定的一件事是,有多少 OOPS 定律会不断被打破!

    【讨论】:

    • 您可以拥有私有常量,但它们当然是在另一个常量范围内,而不是在 OP 想要的方法内。
    • @AndrewMarshall:哇!对我来说是新的。能不能再深入一点。 作用域在另一个常量内让我感到困惑。那么只要你有一个对象作为一个常量,它将你想要的常量封装为私有,它就可以了吗?
    • 给定module A; module B; end; private_constant :B; endA::B只能在A范围内被引用。
    • 哈!!是的,我错了!!错过了 private_constant 方法。谢谢.. :)
    • 是的,我的班级中有私有模块,它通过班级完成......但为了成为一个更好的 oop 编码器,我认为参与更多数据隐藏可能会更好跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 2019-10-12
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    相关资源
    最近更新 更多