What does Ruby constant mean?

后端 未结 6 1669
走了就别回头了
走了就别回头了 2020-12-18 07:58

What does Ruby constants really mean? The following code doesn\'t show any \'constant\' attribute. The warning is there, but I still get to change what A refers to.

相关标签:
6条回答
  • 2020-12-18 08:18

    That's right, constants are just like variables in ruby, but you get a warning if you change them.

    Also, there's one difference with mere variables: You can access constants even if they are defined inside another class or module, for example given this snippet:

    module Constants
      PI = 3,1415
      other = "variable"
    end
    

    You can reach PI doing Constants::PI while Constants::other will not work.

    0 讨论(0)
  • 2020-12-18 08:19

    Yes, Ruby constants aren't enforced, other than printing that warning.

    0 讨论(0)
  • 2020-12-18 08:24

    "Constant" is really a misnomer, the most important aspect of Ruby's "Constants" is not their immutability but their lookup rules.

    see: http://coderrr.wordpress.com/2008/03/11/constant-name-resolution-in-ruby/

    0 讨论(0)
  • 2020-12-18 08:31

    That's right -- assigning to a constant is a warning, not an error; "constants" are just an indicator of how you should use something, not a rule that you do use it that way.

    That may sound horrendous coming from a static-programming world, but it's immensely useful in various metaprogramming facilities, and it enables things that would otherwise be completely impossible in static languages.

    That said, if you really want to make sure people keep their grubby hands off your references, you can use Object#freeze. It's still okay to change what a reference points to with this; you just can't change the contents of the reference itself:

    irb(main):001:0> class Fruit; attr_accessor :name; end
    => nil
    irb(main):002:0> f = Fruit.new
    => #<Fruit:0xb7e06570>
    irb(main):003:0> f.name = "apple"
    => "apple"
    irb(main):004:0> f.freeze                # After freeze, can't touch this Fruit.
    => #<Fruit:0xb7e06570 @name="apple">
    irb(main):005:0> f.name = "banana"
    TypeError: can't modify frozen object    # Kablammo!
        from (irb):5:in `name='
        from (irb):5
    

    But this is okay:

    irb(main):006:0> f = Fruit.new
    => #<Fruit:0xb7dfed84>
    irb(main):007:0> f.name = "banana"
    => "banana"
    
    0 讨论(0)
  • 2020-12-18 08:32

    If you're coming from other programming languages, Ruby handles constants differently than what you may be used to. Constants, in general, take values that do not change through the entire application. The syntax is to use all capital letters while naming your constant so that the application knows how to handle it. For example, to set a constant to hold a baseball team you would declare it this way:

    TEAM = "Angels"
    

    I know you know this much, bear with me here. Typically, other programming languages will not allow you to change the value of TEAM. However, Ruby does not hold you back and takes the last value assigned to the constant. In the above example, I can change its value to:

    TEAM = "Athletics"
    

    Other programming languages would either throw an error or would print the value of Angels. However, Ruby prints the value Athletics because that is the last value assigned to the variable TEAM. Also, it gives a warning message that says that the constant was already initialized and was changed because changing a constant is considered a poor programming practice. But, it still allows you to make the change and follows the Ruby convention of trusting the developer to make the right programming decision. So, be careful while using constants in Ruby since they can be overridden.

    0 讨论(0)
  • 2020-12-18 08:33

    Constants are used to store values that should not be changed. Their names must start with an uppercase letter. By convention, most constant names are written in all uppercase letters with an underscore as word separator, such as SOME_CONSTANT.

    Constants defined within classes can be accessed by all methods of that class. Those created outside a class can be accessed globally (within any method or class).

    class Car
      WHEELS = 4
    
      def initialize
        puts WHEELS
      end
    end
    
    c = Car.new     # Output: 4
    

    Note that Ruby does not stop us from changing the value of a constant, it only issues a warning.

    SOME_CONSTANT = "foo"
    SOME_CONSTANT = "bar"
    warning: already initialized constant SOME_CONSTANT
    warning: previous definition of SOME_CONSTANT was here
    

    In Ruby, all class and module names are constants, but convention dictates they should be written in camel case, such as SomeClass.

    Constants can be accessed from outside the class, even within another class, by using the :: (double colon) operator. To access the WHEELS constant from outside the Car class, we would use Car::WHEELS. The :: operator allows constants, public instance methods and class methods to be accessed from outside the class or module on which they are defined.

    A built-in method called private_constant makes constants private (accessible only within the class on which they were created). The syntax is as follows:

    class Car
      WHEELS = 4
    
      private_constant:WHEELS
    end
    
    Car::WHEELS    # Output: NameError: private constant Car::WHEELS referenced
    
    0 讨论(0)
提交回复
热议问题