Dynamic constant assignment












119















class MyClass
def mymethod
MYCONSTANT = "blah"
end
end


gives me the error:




SyntaxError: dynamic constant assignment error




Why is this considered a dynamic constant? I'm just assigning a string to it.










share|improve this question




















  • 31





    Dynamic Constant is something like Dry Water? :)

    – fl00r
    Jul 15 '11 at 19:42








  • 34





    It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

    – sepp2k
    Jul 15 '11 at 19:46
















119















class MyClass
def mymethod
MYCONSTANT = "blah"
end
end


gives me the error:




SyntaxError: dynamic constant assignment error




Why is this considered a dynamic constant? I'm just assigning a string to it.










share|improve this question




















  • 31





    Dynamic Constant is something like Dry Water? :)

    – fl00r
    Jul 15 '11 at 19:42








  • 34





    It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

    – sepp2k
    Jul 15 '11 at 19:46














119












119








119


26






class MyClass
def mymethod
MYCONSTANT = "blah"
end
end


gives me the error:




SyntaxError: dynamic constant assignment error




Why is this considered a dynamic constant? I'm just assigning a string to it.










share|improve this question
















class MyClass
def mymethod
MYCONSTANT = "blah"
end
end


gives me the error:




SyntaxError: dynamic constant assignment error




Why is this considered a dynamic constant? I'm just assigning a string to it.







ruby






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 10 '12 at 1:00









Andrew Marshall

79.1k16179191




79.1k16179191










asked Jul 15 '11 at 19:38









themirrorthemirror

3,88952960




3,88952960








  • 31





    Dynamic Constant is something like Dry Water? :)

    – fl00r
    Jul 15 '11 at 19:42








  • 34





    It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

    – sepp2k
    Jul 15 '11 at 19:46














  • 31





    Dynamic Constant is something like Dry Water? :)

    – fl00r
    Jul 15 '11 at 19:42








  • 34





    It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

    – sepp2k
    Jul 15 '11 at 19:46








31




31





Dynamic Constant is something like Dry Water? :)

– fl00r
Jul 15 '11 at 19:42







Dynamic Constant is something like Dry Water? :)

– fl00r
Jul 15 '11 at 19:42






34




34





It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

– sepp2k
Jul 15 '11 at 19:46





It doesn't say that the constant is dynamic. It says that the assignment is dynamic.

– sepp2k
Jul 15 '11 at 19:46












7 Answers
7






active

oldest

votes


















121














Your problem is that each time you run the method you are assigning a new value to the constant. This is not allowed, as it makes the constant non-constant; even though the contents of the string are the same (for the moment, anyhow), the actual string object itself is different each time the method is called. For example:



def foo
p "bar".object_id
end

foo #=> 15779172
foo #=> 15779112


Perhaps if you explained your use case—why you want to change the value of a constant in a method—we could help you with a better implementation.



Perhaps you'd rather have an instance variable on the class?



class MyClass
class << self
attr_accessor :my_constant
end
def my_method
self.class.my_constant = "blah"
end
end

p MyClass.my_constant #=> nil
MyClass.new.my_method

p MyClass.my_constant #=> "blah"


If you really want to change the value of a constant in a method, and your constant is a String or an Array, you can 'cheat' and use the #replace method to cause the object to take on a new value without actually changing the object:



class MyClass
BAR = "blah"

def cheat(new_bar)
BAR.replace new_bar
end
end

p MyClass::BAR #=> "blah"
MyClass.new.cheat "whee"
p MyClass::BAR #=> "whee"





share|improve this answer





















  • 19





    The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

    – Arnaud Meuret
    Mar 6 '13 at 16:10






  • 2





    @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

    – Ajedi32
    Dec 1 '13 at 18:31








  • 2





    @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

    – Arnaud Meuret
    Dec 6 '13 at 21:28






  • 2





    @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

    – Ajedi32
    Dec 6 '13 at 21:37











  • @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

    – Arnaud Meuret
    Feb 3 '14 at 9:10



















62














Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.



Under normal circumstances, you should define the constant inside the class itself:



class MyClass
MY_CONSTANT = "foo"
end

MyClass::MY_CONSTANT #=> "foo"


If for some reason though you really do need to define a constant inside a method (perhaps for some type of metaprogramming), you can use const_set:



class MyClass
def my_method
self.class.const_set(:MY_CONSTANT, "foo")
end
end

MyClass::MY_CONSTANT
#=> NameError: uninitialized constant MyClass::MY_CONSTANT

MyClass.new.my_method
MyClass::MY_CONSTANT #=> "foo"


Again though, const_set isn't something you should really have to resort to under normal circumstances. If you're not sure whether you really want to be assigning to constants this way, you may want to consider one of the following alternatives:



Class variables



Class variables behave like constants in many ways. They are properties on a class, and they are accessible in subclasses of the class they are defined on.



The difference is that class variables are meant to be modifiable, and can therefore be assigned to inside methods with no issue.



class MyClass
def self.my_class_variable
@@my_class_variable
end
def my_method
@@my_class_variable = "foo"
end
end
class SubClass < MyClass
end

MyClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
SubClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass

MyClass.new.my_method
MyClass.my_class_variable #=> "foo"
SubClass.my_class_variable #=> "foo"


Class attributes



Class attributes are a sort of "instance variable on a class". They behave a bit like class variables, except that their values are not shared with subclasses.



class MyClass
class << self
attr_accessor :my_class_attribute
end
def my_method
self.class.my_class_attribute = "blah"
end
end
class SubClass < MyClass
end

MyClass.my_class_attribute #=> nil
SubClass.my_class_attribute #=> nil

MyClass.new.my_method
MyClass.my_class_attribute #=> "blah"
SubClass.my_class_attribute #=> nil

SubClass.new.my_method
SubClass.my_class_attribute #=> "blah"


Instance variables



And just for completeness I should probably mention: if you need to assign a value which can only be determined after your class has been instantiated, there's a good chance you might actually be looking for a plain old instance variable.



class MyClass
attr_accessor :instance_variable
def my_method
@instance_variable = "blah"
end
end

my_object = MyClass.new
my_object.instance_variable #=> nil
my_object.my_method
my_object.instance_variable #=> "blah"

MyClass.new.instance_variable #=> nil





share|improve this answer


























  • This is the clearest answer.

    – Snowcrash
    Oct 31 '13 at 3:02











  • const_set is the right answer.

    – robbie613
    Jul 2 '14 at 22:30



















23














In Ruby, any variable whose name starts with a capital letter is a constant and you can only assign to it once. Choose one of these alternatives:



class MyClass
MYCONSTANT = "blah"

def mymethod
MYCONSTANT
end
end

class MyClass
def mymethod
my_constant = "blah"
end
end





share|improve this answer


























  • Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

    – ubienewbie
    Aug 8 '18 at 11:11



















14














Constants in ruby cannot be defined inside methods. See the notes at the bottom of this page, for example






share|improve this answer

































    0














    You can't name a variable with capital letters or Ruby will asume its a constant and will want it to keep it's value constant, in which case changing it's value would be an error an "dynamic constant assignment error". With lower case should be fine



    class MyClass
    def mymethod
    myconstant = "blah"
    end
    end





    share|improve this answer































      0














      Ruby doesn't like that you are assigning the constant inside of a method because it risks re-assignment. Several SO answers before me give the alternative of assigning it outside of a method--but in the class, which is a better place to assign it.






      share|improve this answer



















      • 1





        Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

        – bradbury9
        Sep 10 '18 at 12:49



















      0














      Many thanks to Dorian and Phrogz for reminding me about the array (and hash) method #replace, which can "replace the contents of an array or hash."



      The notion that a CONSTANT's value can be changed, but with an annoying warning, is one of Ruby's few conceptual mis-steps -- these should either be fully immutable, or dump the constant idea altogether. From a coder's perspective, a constant is declarative and intentional, a signal to other that "this value is truly unchangeable once declared/assigned."



      But sometimes an "obvious declaration" actually forecloses other, future useful opportunities. For example...



      There are legitimate use cases where a "constant's" value might really need to be changed: for example, re-loading ARGV from a REPL-like prompt-loop, then rerunning ARGV thru more (subsequent) OptionParser.parse! calls -- voila! Gives "command line args" a whole new dynamic utility.



      The practical problem is either with the presumptive assumption that "ARGV must be a constant", or in optparse's own initialize method, which hard-codes the assignment of ARGV to the instance var @default_argv for subsequent processing -- that array (ARGV) really should be a parameter, encouraging re-parse and re-use, where appropriate. Proper parameterization, with an appropriate default (say, ARGV) would avoid the need to ever change the "constant" ARGV. Just some 2¢-worth of thoughts...






      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f6712298%2fdynamic-constant-assignment%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        7 Answers
        7






        active

        oldest

        votes








        7 Answers
        7






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        121














        Your problem is that each time you run the method you are assigning a new value to the constant. This is not allowed, as it makes the constant non-constant; even though the contents of the string are the same (for the moment, anyhow), the actual string object itself is different each time the method is called. For example:



        def foo
        p "bar".object_id
        end

        foo #=> 15779172
        foo #=> 15779112


        Perhaps if you explained your use case—why you want to change the value of a constant in a method—we could help you with a better implementation.



        Perhaps you'd rather have an instance variable on the class?



        class MyClass
        class << self
        attr_accessor :my_constant
        end
        def my_method
        self.class.my_constant = "blah"
        end
        end

        p MyClass.my_constant #=> nil
        MyClass.new.my_method

        p MyClass.my_constant #=> "blah"


        If you really want to change the value of a constant in a method, and your constant is a String or an Array, you can 'cheat' and use the #replace method to cause the object to take on a new value without actually changing the object:



        class MyClass
        BAR = "blah"

        def cheat(new_bar)
        BAR.replace new_bar
        end
        end

        p MyClass::BAR #=> "blah"
        MyClass.new.cheat "whee"
        p MyClass::BAR #=> "whee"





        share|improve this answer





















        • 19





          The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

          – Arnaud Meuret
          Mar 6 '13 at 16:10






        • 2





          @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

          – Ajedi32
          Dec 1 '13 at 18:31








        • 2





          @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

          – Arnaud Meuret
          Dec 6 '13 at 21:28






        • 2





          @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

          – Ajedi32
          Dec 6 '13 at 21:37











        • @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

          – Arnaud Meuret
          Feb 3 '14 at 9:10
















        121














        Your problem is that each time you run the method you are assigning a new value to the constant. This is not allowed, as it makes the constant non-constant; even though the contents of the string are the same (for the moment, anyhow), the actual string object itself is different each time the method is called. For example:



        def foo
        p "bar".object_id
        end

        foo #=> 15779172
        foo #=> 15779112


        Perhaps if you explained your use case—why you want to change the value of a constant in a method—we could help you with a better implementation.



        Perhaps you'd rather have an instance variable on the class?



        class MyClass
        class << self
        attr_accessor :my_constant
        end
        def my_method
        self.class.my_constant = "blah"
        end
        end

        p MyClass.my_constant #=> nil
        MyClass.new.my_method

        p MyClass.my_constant #=> "blah"


        If you really want to change the value of a constant in a method, and your constant is a String or an Array, you can 'cheat' and use the #replace method to cause the object to take on a new value without actually changing the object:



        class MyClass
        BAR = "blah"

        def cheat(new_bar)
        BAR.replace new_bar
        end
        end

        p MyClass::BAR #=> "blah"
        MyClass.new.cheat "whee"
        p MyClass::BAR #=> "whee"





        share|improve this answer





















        • 19





          The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

          – Arnaud Meuret
          Mar 6 '13 at 16:10






        • 2





          @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

          – Ajedi32
          Dec 1 '13 at 18:31








        • 2





          @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

          – Arnaud Meuret
          Dec 6 '13 at 21:28






        • 2





          @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

          – Ajedi32
          Dec 6 '13 at 21:37











        • @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

          – Arnaud Meuret
          Feb 3 '14 at 9:10














        121












        121








        121







        Your problem is that each time you run the method you are assigning a new value to the constant. This is not allowed, as it makes the constant non-constant; even though the contents of the string are the same (for the moment, anyhow), the actual string object itself is different each time the method is called. For example:



        def foo
        p "bar".object_id
        end

        foo #=> 15779172
        foo #=> 15779112


        Perhaps if you explained your use case—why you want to change the value of a constant in a method—we could help you with a better implementation.



        Perhaps you'd rather have an instance variable on the class?



        class MyClass
        class << self
        attr_accessor :my_constant
        end
        def my_method
        self.class.my_constant = "blah"
        end
        end

        p MyClass.my_constant #=> nil
        MyClass.new.my_method

        p MyClass.my_constant #=> "blah"


        If you really want to change the value of a constant in a method, and your constant is a String or an Array, you can 'cheat' and use the #replace method to cause the object to take on a new value without actually changing the object:



        class MyClass
        BAR = "blah"

        def cheat(new_bar)
        BAR.replace new_bar
        end
        end

        p MyClass::BAR #=> "blah"
        MyClass.new.cheat "whee"
        p MyClass::BAR #=> "whee"





        share|improve this answer















        Your problem is that each time you run the method you are assigning a new value to the constant. This is not allowed, as it makes the constant non-constant; even though the contents of the string are the same (for the moment, anyhow), the actual string object itself is different each time the method is called. For example:



        def foo
        p "bar".object_id
        end

        foo #=> 15779172
        foo #=> 15779112


        Perhaps if you explained your use case—why you want to change the value of a constant in a method—we could help you with a better implementation.



        Perhaps you'd rather have an instance variable on the class?



        class MyClass
        class << self
        attr_accessor :my_constant
        end
        def my_method
        self.class.my_constant = "blah"
        end
        end

        p MyClass.my_constant #=> nil
        MyClass.new.my_method

        p MyClass.my_constant #=> "blah"


        If you really want to change the value of a constant in a method, and your constant is a String or an Array, you can 'cheat' and use the #replace method to cause the object to take on a new value without actually changing the object:



        class MyClass
        BAR = "blah"

        def cheat(new_bar)
        BAR.replace new_bar
        end
        end

        p MyClass::BAR #=> "blah"
        MyClass.new.cheat "whee"
        p MyClass::BAR #=> "whee"






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 1 '17 at 22:03









        Dorian

        12.8k37385




        12.8k37385










        answered Jul 15 '11 at 19:53









        PhrogzPhrogz

        221k79541621




        221k79541621








        • 19





          The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

          – Arnaud Meuret
          Mar 6 '13 at 16:10






        • 2





          @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

          – Ajedi32
          Dec 1 '13 at 18:31








        • 2





          @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

          – Arnaud Meuret
          Dec 6 '13 at 21:28






        • 2





          @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

          – Ajedi32
          Dec 6 '13 at 21:37











        • @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

          – Arnaud Meuret
          Feb 3 '14 at 9:10














        • 19





          The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

          – Arnaud Meuret
          Mar 6 '13 at 16:10






        • 2





          @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

          – Ajedi32
          Dec 1 '13 at 18:31








        • 2





          @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

          – Arnaud Meuret
          Dec 6 '13 at 21:28






        • 2





          @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

          – Ajedi32
          Dec 6 '13 at 21:37











        • @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

          – Arnaud Meuret
          Feb 3 '14 at 9:10








        19




        19





        The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

        – Arnaud Meuret
        Mar 6 '13 at 16:10





        The OP never said he wanted to change the value of the constant but just wanted to assign a value. The frequent use case leading to this Ruby error is when you build the value in a method from other run-time assets (variables, command-line arguments, ENV), typically in a constructor e.g. def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end. It's one of those cases where Ruby has no simple way.

        – Arnaud Meuret
        Mar 6 '13 at 16:10




        2




        2





        @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

        – Ajedi32
        Dec 1 '13 at 18:31







        @ArnaudMeuret For that case you want an instance variable (e.g. @variable), not a constant. Otherwise you'd be re-assigning DB every time you instantiated a new instance of that class.

        – Ajedi32
        Dec 1 '13 at 18:31






        2




        2





        @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

        – Arnaud Meuret
        Dec 6 '13 at 21:28





        @Ajedi32 This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.

        – Arnaud Meuret
        Dec 6 '13 at 21:28




        2




        2





        @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

        – Ajedi32
        Dec 6 '13 at 21:37





        @ArnaudMeuret I'll admit I've never used Sequel before so I can't say this with 100% certainty, but just glancing over the documentation for Sequel I see nothing that says you HAVE to assign the result of Sequel.connect to a constant named DB. In fact, the documentation explicitly says that that's just a recommendation. That doesn't sound like an external constraint to me.

        – Ajedi32
        Dec 6 '13 at 21:37













        @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

        – Arnaud Meuret
        Feb 3 '14 at 9:10





        @Ajedi32 1) I never wrote that (name of the constant or even that you had to keep it somewhere) it is just an example 2) The constraint being that your software may not have the necessary information until you typically are in a dynamic context.

        – Arnaud Meuret
        Feb 3 '14 at 9:10













        62














        Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.



        Under normal circumstances, you should define the constant inside the class itself:



        class MyClass
        MY_CONSTANT = "foo"
        end

        MyClass::MY_CONSTANT #=> "foo"


        If for some reason though you really do need to define a constant inside a method (perhaps for some type of metaprogramming), you can use const_set:



        class MyClass
        def my_method
        self.class.const_set(:MY_CONSTANT, "foo")
        end
        end

        MyClass::MY_CONSTANT
        #=> NameError: uninitialized constant MyClass::MY_CONSTANT

        MyClass.new.my_method
        MyClass::MY_CONSTANT #=> "foo"


        Again though, const_set isn't something you should really have to resort to under normal circumstances. If you're not sure whether you really want to be assigning to constants this way, you may want to consider one of the following alternatives:



        Class variables



        Class variables behave like constants in many ways. They are properties on a class, and they are accessible in subclasses of the class they are defined on.



        The difference is that class variables are meant to be modifiable, and can therefore be assigned to inside methods with no issue.



        class MyClass
        def self.my_class_variable
        @@my_class_variable
        end
        def my_method
        @@my_class_variable = "foo"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass
        SubClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass

        MyClass.new.my_method
        MyClass.my_class_variable #=> "foo"
        SubClass.my_class_variable #=> "foo"


        Class attributes



        Class attributes are a sort of "instance variable on a class". They behave a bit like class variables, except that their values are not shared with subclasses.



        class MyClass
        class << self
        attr_accessor :my_class_attribute
        end
        def my_method
        self.class.my_class_attribute = "blah"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_attribute #=> nil
        SubClass.my_class_attribute #=> nil

        MyClass.new.my_method
        MyClass.my_class_attribute #=> "blah"
        SubClass.my_class_attribute #=> nil

        SubClass.new.my_method
        SubClass.my_class_attribute #=> "blah"


        Instance variables



        And just for completeness I should probably mention: if you need to assign a value which can only be determined after your class has been instantiated, there's a good chance you might actually be looking for a plain old instance variable.



        class MyClass
        attr_accessor :instance_variable
        def my_method
        @instance_variable = "blah"
        end
        end

        my_object = MyClass.new
        my_object.instance_variable #=> nil
        my_object.my_method
        my_object.instance_variable #=> "blah"

        MyClass.new.instance_variable #=> nil





        share|improve this answer


























        • This is the clearest answer.

          – Snowcrash
          Oct 31 '13 at 3:02











        • const_set is the right answer.

          – robbie613
          Jul 2 '14 at 22:30
















        62














        Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.



        Under normal circumstances, you should define the constant inside the class itself:



        class MyClass
        MY_CONSTANT = "foo"
        end

        MyClass::MY_CONSTANT #=> "foo"


        If for some reason though you really do need to define a constant inside a method (perhaps for some type of metaprogramming), you can use const_set:



        class MyClass
        def my_method
        self.class.const_set(:MY_CONSTANT, "foo")
        end
        end

        MyClass::MY_CONSTANT
        #=> NameError: uninitialized constant MyClass::MY_CONSTANT

        MyClass.new.my_method
        MyClass::MY_CONSTANT #=> "foo"


        Again though, const_set isn't something you should really have to resort to under normal circumstances. If you're not sure whether you really want to be assigning to constants this way, you may want to consider one of the following alternatives:



        Class variables



        Class variables behave like constants in many ways. They are properties on a class, and they are accessible in subclasses of the class they are defined on.



        The difference is that class variables are meant to be modifiable, and can therefore be assigned to inside methods with no issue.



        class MyClass
        def self.my_class_variable
        @@my_class_variable
        end
        def my_method
        @@my_class_variable = "foo"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass
        SubClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass

        MyClass.new.my_method
        MyClass.my_class_variable #=> "foo"
        SubClass.my_class_variable #=> "foo"


        Class attributes



        Class attributes are a sort of "instance variable on a class". They behave a bit like class variables, except that their values are not shared with subclasses.



        class MyClass
        class << self
        attr_accessor :my_class_attribute
        end
        def my_method
        self.class.my_class_attribute = "blah"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_attribute #=> nil
        SubClass.my_class_attribute #=> nil

        MyClass.new.my_method
        MyClass.my_class_attribute #=> "blah"
        SubClass.my_class_attribute #=> nil

        SubClass.new.my_method
        SubClass.my_class_attribute #=> "blah"


        Instance variables



        And just for completeness I should probably mention: if you need to assign a value which can only be determined after your class has been instantiated, there's a good chance you might actually be looking for a plain old instance variable.



        class MyClass
        attr_accessor :instance_variable
        def my_method
        @instance_variable = "blah"
        end
        end

        my_object = MyClass.new
        my_object.instance_variable #=> nil
        my_object.my_method
        my_object.instance_variable #=> "blah"

        MyClass.new.instance_variable #=> nil





        share|improve this answer


























        • This is the clearest answer.

          – Snowcrash
          Oct 31 '13 at 3:02











        • const_set is the right answer.

          – robbie613
          Jul 2 '14 at 22:30














        62












        62








        62







        Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.



        Under normal circumstances, you should define the constant inside the class itself:



        class MyClass
        MY_CONSTANT = "foo"
        end

        MyClass::MY_CONSTANT #=> "foo"


        If for some reason though you really do need to define a constant inside a method (perhaps for some type of metaprogramming), you can use const_set:



        class MyClass
        def my_method
        self.class.const_set(:MY_CONSTANT, "foo")
        end
        end

        MyClass::MY_CONSTANT
        #=> NameError: uninitialized constant MyClass::MY_CONSTANT

        MyClass.new.my_method
        MyClass::MY_CONSTANT #=> "foo"


        Again though, const_set isn't something you should really have to resort to under normal circumstances. If you're not sure whether you really want to be assigning to constants this way, you may want to consider one of the following alternatives:



        Class variables



        Class variables behave like constants in many ways. They are properties on a class, and they are accessible in subclasses of the class they are defined on.



        The difference is that class variables are meant to be modifiable, and can therefore be assigned to inside methods with no issue.



        class MyClass
        def self.my_class_variable
        @@my_class_variable
        end
        def my_method
        @@my_class_variable = "foo"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass
        SubClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass

        MyClass.new.my_method
        MyClass.my_class_variable #=> "foo"
        SubClass.my_class_variable #=> "foo"


        Class attributes



        Class attributes are a sort of "instance variable on a class". They behave a bit like class variables, except that their values are not shared with subclasses.



        class MyClass
        class << self
        attr_accessor :my_class_attribute
        end
        def my_method
        self.class.my_class_attribute = "blah"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_attribute #=> nil
        SubClass.my_class_attribute #=> nil

        MyClass.new.my_method
        MyClass.my_class_attribute #=> "blah"
        SubClass.my_class_attribute #=> nil

        SubClass.new.my_method
        SubClass.my_class_attribute #=> "blah"


        Instance variables



        And just for completeness I should probably mention: if you need to assign a value which can only be determined after your class has been instantiated, there's a good chance you might actually be looking for a plain old instance variable.



        class MyClass
        attr_accessor :instance_variable
        def my_method
        @instance_variable = "blah"
        end
        end

        my_object = MyClass.new
        my_object.instance_variable #=> nil
        my_object.my_method
        my_object.instance_variable #=> "blah"

        MyClass.new.instance_variable #=> nil





        share|improve this answer















        Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.



        Under normal circumstances, you should define the constant inside the class itself:



        class MyClass
        MY_CONSTANT = "foo"
        end

        MyClass::MY_CONSTANT #=> "foo"


        If for some reason though you really do need to define a constant inside a method (perhaps for some type of metaprogramming), you can use const_set:



        class MyClass
        def my_method
        self.class.const_set(:MY_CONSTANT, "foo")
        end
        end

        MyClass::MY_CONSTANT
        #=> NameError: uninitialized constant MyClass::MY_CONSTANT

        MyClass.new.my_method
        MyClass::MY_CONSTANT #=> "foo"


        Again though, const_set isn't something you should really have to resort to under normal circumstances. If you're not sure whether you really want to be assigning to constants this way, you may want to consider one of the following alternatives:



        Class variables



        Class variables behave like constants in many ways. They are properties on a class, and they are accessible in subclasses of the class they are defined on.



        The difference is that class variables are meant to be modifiable, and can therefore be assigned to inside methods with no issue.



        class MyClass
        def self.my_class_variable
        @@my_class_variable
        end
        def my_method
        @@my_class_variable = "foo"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass
        SubClass.my_class_variable
        #=> NameError: uninitialized class variable @@my_class_variable in MyClass

        MyClass.new.my_method
        MyClass.my_class_variable #=> "foo"
        SubClass.my_class_variable #=> "foo"


        Class attributes



        Class attributes are a sort of "instance variable on a class". They behave a bit like class variables, except that their values are not shared with subclasses.



        class MyClass
        class << self
        attr_accessor :my_class_attribute
        end
        def my_method
        self.class.my_class_attribute = "blah"
        end
        end
        class SubClass < MyClass
        end

        MyClass.my_class_attribute #=> nil
        SubClass.my_class_attribute #=> nil

        MyClass.new.my_method
        MyClass.my_class_attribute #=> "blah"
        SubClass.my_class_attribute #=> nil

        SubClass.new.my_method
        SubClass.my_class_attribute #=> "blah"


        Instance variables



        And just for completeness I should probably mention: if you need to assign a value which can only be determined after your class has been instantiated, there's a good chance you might actually be looking for a plain old instance variable.



        class MyClass
        attr_accessor :instance_variable
        def my_method
        @instance_variable = "blah"
        end
        end

        my_object = MyClass.new
        my_object.instance_variable #=> nil
        my_object.my_method
        my_object.instance_variable #=> "blah"

        MyClass.new.instance_variable #=> nil






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 25 '15 at 23:26

























        answered Sep 14 '12 at 14:25









        Ajedi32Ajedi32

        25.2k1194127




        25.2k1194127













        • This is the clearest answer.

          – Snowcrash
          Oct 31 '13 at 3:02











        • const_set is the right answer.

          – robbie613
          Jul 2 '14 at 22:30



















        • This is the clearest answer.

          – Snowcrash
          Oct 31 '13 at 3:02











        • const_set is the right answer.

          – robbie613
          Jul 2 '14 at 22:30

















        This is the clearest answer.

        – Snowcrash
        Oct 31 '13 at 3:02





        This is the clearest answer.

        – Snowcrash
        Oct 31 '13 at 3:02













        const_set is the right answer.

        – robbie613
        Jul 2 '14 at 22:30





        const_set is the right answer.

        – robbie613
        Jul 2 '14 at 22:30











        23














        In Ruby, any variable whose name starts with a capital letter is a constant and you can only assign to it once. Choose one of these alternatives:



        class MyClass
        MYCONSTANT = "blah"

        def mymethod
        MYCONSTANT
        end
        end

        class MyClass
        def mymethod
        my_constant = "blah"
        end
        end





        share|improve this answer


























        • Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

          – ubienewbie
          Aug 8 '18 at 11:11
















        23














        In Ruby, any variable whose name starts with a capital letter is a constant and you can only assign to it once. Choose one of these alternatives:



        class MyClass
        MYCONSTANT = "blah"

        def mymethod
        MYCONSTANT
        end
        end

        class MyClass
        def mymethod
        my_constant = "blah"
        end
        end





        share|improve this answer


























        • Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

          – ubienewbie
          Aug 8 '18 at 11:11














        23












        23








        23







        In Ruby, any variable whose name starts with a capital letter is a constant and you can only assign to it once. Choose one of these alternatives:



        class MyClass
        MYCONSTANT = "blah"

        def mymethod
        MYCONSTANT
        end
        end

        class MyClass
        def mymethod
        my_constant = "blah"
        end
        end





        share|improve this answer















        In Ruby, any variable whose name starts with a capital letter is a constant and you can only assign to it once. Choose one of these alternatives:



        class MyClass
        MYCONSTANT = "blah"

        def mymethod
        MYCONSTANT
        end
        end

        class MyClass
        def mymethod
        my_constant = "blah"
        end
        end






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 1 '17 at 22:03









        Dorian

        12.8k37385




        12.8k37385










        answered Jul 15 '11 at 19:59









        David GraysonDavid Grayson

        57.1k18104148




        57.1k18104148













        • Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

          – ubienewbie
          Aug 8 '18 at 11:11



















        • Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

          – ubienewbie
          Aug 8 '18 at 11:11

















        Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

        – ubienewbie
        Aug 8 '18 at 11:11





        Thank goodness someone mentioned that "any variable whose name starts with a capital letter is a constant!"

        – ubienewbie
        Aug 8 '18 at 11:11











        14














        Constants in ruby cannot be defined inside methods. See the notes at the bottom of this page, for example






        share|improve this answer






























          14














          Constants in ruby cannot be defined inside methods. See the notes at the bottom of this page, for example






          share|improve this answer




























            14












            14








            14







            Constants in ruby cannot be defined inside methods. See the notes at the bottom of this page, for example






            share|improve this answer















            Constants in ruby cannot be defined inside methods. See the notes at the bottom of this page, for example







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 15 '11 at 19:49

























            answered Jul 15 '11 at 19:41









            chrispandachrispanda

            2,93411422




            2,93411422























                0














                You can't name a variable with capital letters or Ruby will asume its a constant and will want it to keep it's value constant, in which case changing it's value would be an error an "dynamic constant assignment error". With lower case should be fine



                class MyClass
                def mymethod
                myconstant = "blah"
                end
                end





                share|improve this answer




























                  0














                  You can't name a variable with capital letters or Ruby will asume its a constant and will want it to keep it's value constant, in which case changing it's value would be an error an "dynamic constant assignment error". With lower case should be fine



                  class MyClass
                  def mymethod
                  myconstant = "blah"
                  end
                  end





                  share|improve this answer


























                    0












                    0








                    0







                    You can't name a variable with capital letters or Ruby will asume its a constant and will want it to keep it's value constant, in which case changing it's value would be an error an "dynamic constant assignment error". With lower case should be fine



                    class MyClass
                    def mymethod
                    myconstant = "blah"
                    end
                    end





                    share|improve this answer













                    You can't name a variable with capital letters or Ruby will asume its a constant and will want it to keep it's value constant, in which case changing it's value would be an error an "dynamic constant assignment error". With lower case should be fine



                    class MyClass
                    def mymethod
                    myconstant = "blah"
                    end
                    end






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 22 '17 at 19:01









                    Jose PaezJose Paez

                    235




                    235























                        0














                        Ruby doesn't like that you are assigning the constant inside of a method because it risks re-assignment. Several SO answers before me give the alternative of assigning it outside of a method--but in the class, which is a better place to assign it.






                        share|improve this answer



















                        • 1





                          Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                          – bradbury9
                          Sep 10 '18 at 12:49
















                        0














                        Ruby doesn't like that you are assigning the constant inside of a method because it risks re-assignment. Several SO answers before me give the alternative of assigning it outside of a method--but in the class, which is a better place to assign it.






                        share|improve this answer



















                        • 1





                          Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                          – bradbury9
                          Sep 10 '18 at 12:49














                        0












                        0








                        0







                        Ruby doesn't like that you are assigning the constant inside of a method because it risks re-assignment. Several SO answers before me give the alternative of assigning it outside of a method--but in the class, which is a better place to assign it.






                        share|improve this answer













                        Ruby doesn't like that you are assigning the constant inside of a method because it risks re-assignment. Several SO answers before me give the alternative of assigning it outside of a method--but in the class, which is a better place to assign it.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Sep 10 '18 at 12:40









                        JohnJohn

                        12




                        12








                        • 1





                          Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                          – bradbury9
                          Sep 10 '18 at 12:49














                        • 1





                          Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                          – bradbury9
                          Sep 10 '18 at 12:49








                        1




                        1





                        Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                        – bradbury9
                        Sep 10 '18 at 12:49





                        Weicome to SO John. Yo may consider improving this answer adding some sample code of what you are describing.

                        – bradbury9
                        Sep 10 '18 at 12:49











                        0














                        Many thanks to Dorian and Phrogz for reminding me about the array (and hash) method #replace, which can "replace the contents of an array or hash."



                        The notion that a CONSTANT's value can be changed, but with an annoying warning, is one of Ruby's few conceptual mis-steps -- these should either be fully immutable, or dump the constant idea altogether. From a coder's perspective, a constant is declarative and intentional, a signal to other that "this value is truly unchangeable once declared/assigned."



                        But sometimes an "obvious declaration" actually forecloses other, future useful opportunities. For example...



                        There are legitimate use cases where a "constant's" value might really need to be changed: for example, re-loading ARGV from a REPL-like prompt-loop, then rerunning ARGV thru more (subsequent) OptionParser.parse! calls -- voila! Gives "command line args" a whole new dynamic utility.



                        The practical problem is either with the presumptive assumption that "ARGV must be a constant", or in optparse's own initialize method, which hard-codes the assignment of ARGV to the instance var @default_argv for subsequent processing -- that array (ARGV) really should be a parameter, encouraging re-parse and re-use, where appropriate. Proper parameterization, with an appropriate default (say, ARGV) would avoid the need to ever change the "constant" ARGV. Just some 2¢-worth of thoughts...






                        share|improve this answer




























                          0














                          Many thanks to Dorian and Phrogz for reminding me about the array (and hash) method #replace, which can "replace the contents of an array or hash."



                          The notion that a CONSTANT's value can be changed, but with an annoying warning, is one of Ruby's few conceptual mis-steps -- these should either be fully immutable, or dump the constant idea altogether. From a coder's perspective, a constant is declarative and intentional, a signal to other that "this value is truly unchangeable once declared/assigned."



                          But sometimes an "obvious declaration" actually forecloses other, future useful opportunities. For example...



                          There are legitimate use cases where a "constant's" value might really need to be changed: for example, re-loading ARGV from a REPL-like prompt-loop, then rerunning ARGV thru more (subsequent) OptionParser.parse! calls -- voila! Gives "command line args" a whole new dynamic utility.



                          The practical problem is either with the presumptive assumption that "ARGV must be a constant", or in optparse's own initialize method, which hard-codes the assignment of ARGV to the instance var @default_argv for subsequent processing -- that array (ARGV) really should be a parameter, encouraging re-parse and re-use, where appropriate. Proper parameterization, with an appropriate default (say, ARGV) would avoid the need to ever change the "constant" ARGV. Just some 2¢-worth of thoughts...






                          share|improve this answer


























                            0












                            0








                            0







                            Many thanks to Dorian and Phrogz for reminding me about the array (and hash) method #replace, which can "replace the contents of an array or hash."



                            The notion that a CONSTANT's value can be changed, but with an annoying warning, is one of Ruby's few conceptual mis-steps -- these should either be fully immutable, or dump the constant idea altogether. From a coder's perspective, a constant is declarative and intentional, a signal to other that "this value is truly unchangeable once declared/assigned."



                            But sometimes an "obvious declaration" actually forecloses other, future useful opportunities. For example...



                            There are legitimate use cases where a "constant's" value might really need to be changed: for example, re-loading ARGV from a REPL-like prompt-loop, then rerunning ARGV thru more (subsequent) OptionParser.parse! calls -- voila! Gives "command line args" a whole new dynamic utility.



                            The practical problem is either with the presumptive assumption that "ARGV must be a constant", or in optparse's own initialize method, which hard-codes the assignment of ARGV to the instance var @default_argv for subsequent processing -- that array (ARGV) really should be a parameter, encouraging re-parse and re-use, where appropriate. Proper parameterization, with an appropriate default (say, ARGV) would avoid the need to ever change the "constant" ARGV. Just some 2¢-worth of thoughts...






                            share|improve this answer













                            Many thanks to Dorian and Phrogz for reminding me about the array (and hash) method #replace, which can "replace the contents of an array or hash."



                            The notion that a CONSTANT's value can be changed, but with an annoying warning, is one of Ruby's few conceptual mis-steps -- these should either be fully immutable, or dump the constant idea altogether. From a coder's perspective, a constant is declarative and intentional, a signal to other that "this value is truly unchangeable once declared/assigned."



                            But sometimes an "obvious declaration" actually forecloses other, future useful opportunities. For example...



                            There are legitimate use cases where a "constant's" value might really need to be changed: for example, re-loading ARGV from a REPL-like prompt-loop, then rerunning ARGV thru more (subsequent) OptionParser.parse! calls -- voila! Gives "command line args" a whole new dynamic utility.



                            The practical problem is either with the presumptive assumption that "ARGV must be a constant", or in optparse's own initialize method, which hard-codes the assignment of ARGV to the instance var @default_argv for subsequent processing -- that array (ARGV) really should be a parameter, encouraging re-parse and re-use, where appropriate. Proper parameterization, with an appropriate default (say, ARGV) would avoid the need to ever change the "constant" ARGV. Just some 2¢-worth of thoughts...







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 13 '18 at 21:06









                            Lorin RickerLorin Ricker

                            566




                            566






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f6712298%2fdynamic-constant-assignment%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Bressuire

                                Vorschmack

                                Quarantine