Ruby constants

Ruby constants

We don’t have a lot of Ruby constants in the bootrAils starter. However, it’s always good to know how they work when the need arises. “Constants” are variables that are not meant to be changed. Let’s see how. In this article we will use the ruby console, if you are in a Rails environment, you can get it by typing bin/rails console .

How to define a Ruby constant

Constants begin with an uppercase letter.

Constants defined within a class or module can be directly accessed from the inside. Those defined outside a class or module can still be accessed globally.

As you can notice, ICE and BOIL are freely accessed from the class where they are defined. From the outside :

Ruby constants that will fail

Constants cannot be defined inside a method., constants cannot start with a lower case..

This will produce the following error on call :

Uninitialized Constant Error

This kind of error will often happen if you code with Ruby-on-Rails or any other framework. It often means a class or constant inside a module wasn’t found. You can easily recreate this error on your computer :

And then try simply to access a constant that doesn’t exists :

Changing… A Ruby constant

This is something disturbing if you come from another language : Ruby constants can be changed without the raise of any error.

A warning is raised, but the program still continues.

If you want to avoid this default behaviour, you have to freeze your constant.

For this example, I’m going to freeze… the ice.

It doesn’t really work, because you can still make Water::ICE = 42 and have a simple warning.

A Ruby constant isn’t actually immutable, and you can’t freeze a variable.

See this excellent StackOverflow answer to circumvent this problem : https://stackoverflow.com/a/26542453/2595513

DEV Community

DEV Community

Carlos Ferrer

Posted on Oct 5, 2023 • Updated on Oct 17, 2023

Mastering Variables and Constants in Ruby: The Beauty of Flexibility and Consistency

Image description

Ruby , a dynamic, object-oriented programming language, is known for its convenience and simplicity. One of the features that make Ruby so special is the way it treats variables and constants. In this article, we will delve into the depths of this language to understand how Ruby handles these essential elements and how you can elegantly use them in your own projects.

Variables in Ruby: Flexibility that inspires creativity

Variables in Ruby are like magic boxes that can contain any type of data — numbers (integers and decimals), strings, objects, and more. The simple act of assigning a value to a variable is known as "assignment". Let's look at an example:

Here, name and age are variables that contain a string and a number respectively. Ruby does not require you to declare the type of variable - it is dynamic and will automatically deduce the type based on the assigned value.

Another notable aspect is that variables in Ruby begin with lowercase letters or the _ symbol. They are case sensitive, which means that name and Name are different variables.

Constants in Ruby: Stability amid change

Constants in Ruby are values that should not be changed during program execution. The decision followed by Ruby developers is to write constants with all letters in capital letters, making them easily distinguishable from variables. Let's look at an example:

These constants are immutable, and if you try to reassign a value to them, you will receive a warning. However, it is important to note that Ruby does not prevent modifying the contents of objects assigned to a constant. For example:

Scope of Variables and Constants

Ruby also offers different scopes for variables and constants:

  • Local scope : Variables defined within a method or block are considered local and can only be accessed within that context. Let's see:
  • Instance scope : Instance variables start with @ and are accessible in every instance of a class. For example:
  • Class scope: Class variables start with @@ and are shared by all instances of a class. Let's see:
  • Global scope : Global variables start with $ and can be accessed anywhere in the code, making them a powerful feature, but one that should be used with caution. Let's see:

The elegance of flexibility and consistency

Ruby, with its simplicity and flexibility, makes programming a creative and elegant experience. Variables and constants play a crucial role in this journey, allowing developers to express their ideas in an intuitive and consistent way. By understanding the difference between variables and constants in Ruby, as well as the scopes in which they operate, you will be prepared to write elegant and effective Ruby code. Enjoy the beauty of this language and let your creativity flow in the art of programming. I hope this article has been an enlightening introduction to the world of variables and constants in Ruby. As you deepen your knowledge, you will discover even more reasons to fall in love with this versatile and expressive language. Happy coding!

Top comments (0)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

developedbyjk profile image

12 Benefits Of Learning Python 🐍

developedbyjk - May 25

vyan profile image

Styling in ReactJS: Exploring the Best Libraries

Vishal Yadav - Jun 3

mdarifulhaque profile image

140. Word Break II

MD ARIFUL HAQUE - May 25

thomascansino profile image

[DAY 42-47] I Built A Cash Register App

Thomas Cansino - Jun 3

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Ruby Metaprogramming Is Even Cooler Than It Sounds

Ruby metaprogramming, one of the most interesting aspects of Ruby, enables the programming language to achieve an extreme level of expressiveness. It is because of this very feature that many gems, such as RSpec and ActiveRecord, can work the way they do. In this article, Toptal engineer Nikola Todorovic demystifies Ruby metaprogramming using some examples that are relevant to everyday programming and aims to bring it closer to average Ruby developers.

Ruby Metaprogramming Is Even Cooler Than It Sounds

By Nikola Todorovic

Nikola has an MCE degree and almost a decade of experience in software development. His passions are Ruby on Rails and startups.

You often hear that metaprogramming is something that only Ruby ninjas use, and that it simply isn’t for common mortals. But the truth is that metaprogramming isn’t something scary at all. This blog post will serve to challenge this type of thinking and to get metaprogramming closer to the average Ruby developer so that they can also reap its benefits.

It should be noted that metaprogramming could mean a lot and it can often be very misused and go to the extreme when it comes to usage so I will try to throw in some real world examples that everyone could use in everyday programming.

  • Metaprogramming

Metaprogramming is a technique by which you can write code that writes code by itself dynamically at runtime. This means you can define methods and classes during runtime. Crazy, right? In a nutshell, using metaprogramming you can reopen and modify classes, catch methods that don’t exist and create them on the fly, create code that is DRY by avoiding repetitions, and more.

Before we dive into serious metaprogramming we must explore the basics. And the best way to do that is by example. Let’s start with one and understand Ruby metaprogramming step-by-step. You can probably guess what this code is doing:

We have defined a class with two methods. The first method in this class is a class method and the second one is an instance method. This is basic stuff in Ruby, but there is much more happening behind this code which we need to understand before we proceed further. It is worth pointing out that the class Developer itself is actually an object. In Ruby everything is an object, including classes. Since Developer is an instance, it is an instance of class Class . Here is how the Ruby object model looks like:

Ruby object model

One important thing to understand here is the meaning of self . The frontend method is a regular method that is available on instances of class Developer , but why is backend method a class method? Every piece of code executed in Ruby is executed against a particular self . When the Ruby interpreter executes any code it always keeps track of the value self for any given line. self is always referring to some object but that object can change based on the code executed. For example, inside a class definition, the self refers to the class itself which is an instance of class Class .

Inside instance methods, self refers to an instance of the class.

Inside class methods, self refers to the class itself in a way (which will be discussed in more detail later in this article):

This is fine, but what is a class method after all? Before answering that question we need to mention the existence of something called metaclass, also known as singleton class and eigenclass. Class method frontend that we defined earlier is nothing but an instance method defined in the metaclass for the object Developer ! A metaclass is essentially a class that Ruby creates and inserts into the inheritance hierarchy to hold class methods, thus not interfering with instances that are created from the class.

Metaclasses

Every object in Ruby has its own metaclass . It is somehow invisible to a developer, but it is there and you can use it very easily. Since our class Developer is essentially an object, it has its own metaclass. As an example let’s create an object of a class String and manipulate its metaclass:

What we did here is we added a singleton method something to an object. The difference between class methods and singleton methods is that class methods are available to all instances of a class object while singleton methods are available only to that single instance. Class methods are widely used while singleton methods not so much, but both types of methods are added to a metaclass of that object.

The previous example could be re-written like this:

The syntax is different but it effectively does the same thing. Now let’s go back to the previous example where we created Developer class and explore some other syntaxes to define a class method:

This is a basic definition that almost everybody uses.

This is the same thing, we are defining the backend class method for Developer . We didn’t use self but defining a method like this effectively makes it a class method.

Again, we are defining a class method, but using syntax similar to one we used to define a singleton method for a String object. You may notice that we used self here which refers to a Developer object itself. First we opened Developer class, making self equal to the Developer class. Next, we do class << self , making self equal to Developer ’s metaclass. Then we define a method backend on Developer ’s metaclass.

By defining a block like this, we are setting self to Developer ’s metaclass for the duration of the block. As a result, the backend method is added to Developer ’s metaclass, rather than the class itself.

Let’s see how this metaclass behaves in the inheritance tree:

Metaclass in inheritence tree

As you saw in previous examples, there’s no real proof that metaclass even exists. But we can use a little hack that can show us the existence of this invisible class:

If we define an instance method in Object class (yes, we can reopen any class anytime, that’s yet another beauty of metaprogramming), we will have a self referring to the Object object inside it. We can then use class << self syntax to change the current self to point to the metaclass of the current object. Since the current object is Object class itself this would be the instance’s metaclass. The method returns self which is at this point a metaclass itself. So by calling this instance method on any object we can get a metaclass of that object. Let’s define our Developer class again and start exploring a little:

And for the crescendo, let’s see the proof that frontend is an instance method of a class and backend is an instance method of a metaclass:

Although, to get the metaclass you don’t need to actually reopen Object and add this hack. You can use singleton_class that Ruby provides. It is the same as metaclass_example we added but with this hack you can actually see how Ruby works under the hood:

Defining Methods Using “class_eval” and “instance_eval”

There’s one more way to create a class method, and that is by using instance_eval :

This piece of code Ruby interpreter evaluates in the context of an instance, which is in this case a Developer object. And when you are defining a method on an object you are creating either a class method or a singleton method. In this case it is a class method - to be exact, class methods are singleton methods but singleton methods of a class, while the others are singleton methods of an object.

On the other hand, class_eval evaluates the code in the context of a class instead of an instance. It practically reopens the class. Here is how class_eval can be used to create an instance method:

To summarize, when you call class_eval method, you change self to refer to the original class and when you call instance_eval , self changes to refer to original class’ metaclass.

Defining Missing Methods on the Fly

One more piece of metaprogramming puzzle is method_missing . When you call a method on an object, Ruby first goes into the class and browses its instance methods. If it doesn’t find the method there, it continues search up the ancestors chain. If Ruby still doesn’t find the method, it calls another method named method_missing which is an instance method of Kernel that every object inherits. Since we are sure that Ruby is going to call this method eventually for missing methods, we can use this to implement some tricks.

define_method is a method defined in Module class which you can use to create methods dynamically. To use define_method , you call it with the name of the new method and a block where the parameters of the block become the parameters of the new method. What’s the difference between using def to create a method and define_method ? There’s not much difference except you can use define_method in combination with method_missing to write DRY code. To be exact, you can use define_method instead of def to manipulate scopes when defining a class, but that’s a whole other story. Let’s take a look at a simple example:

This shows how define_method was used to create an instance method without using a def . However, there’s much more we can do with them. Let’s take a look at this code snippet:

This code isn’t DRY, but using define_method we can make it DRY:

That’s much better, but still not perfect. Why? If we want to add a new method coding_debug for example, we need to put this "debug" into the array. But using method_missing we can fix this:

This piece of code is a little complicated so let’s break it down. Calling a method that doesn’t exist will fire up method_missing . Here, we want to create a new method only when the method name starts with "coding_" . Otherwise we just call super to do the work of reporting a method that is actually missing. And we are simply using define_method to create that new method. That’s it! With this piece of code we can create literally thousands of new methods starting with "coding_" , and that fact is what makes our code DRY. Since define_method happens to be private to Module , we need to use send to invoke it.

Wrapping up

This is just the tip of the iceberg. To become a Ruby Jedi , this is the starting point. After you master these building blocks of metaprogramming and truly understand its essence, you can proceed to something more complex, for example create your own Domain-specific Language (DSL). DSL is a topic in itself but these basic concepts are a prerequisite to understanding advanced topics. Some of the most used gems in Rails were built in this way and you probably used its DSL without even knowing it, such as RSpec and ActiveRecord.

Hopefully this article can get you one step closer to understanding metaprogramming and maybe even building your own DSL, which you can use to code more efficiently.

Further Reading on the Toptal Blog:

  • Creating a Ruby DSL: A Guide to Advanced Metaprogramming
  • Code Writing Code: An Introduction to the Theory and Practice of Modern Metaprogramming
  • Rails Service Objects: A Comprehensive Guide
  • Ruby Algorithm Documentation with AsciiDoc and Knitr
  • Getting Started with the Elixir Programming Language

Nikola Todorovic

Belgrade, Serbia

Member since August 4, 2015

About the author

World-class articles, delivered weekly.

By entering your email, you are agreeing to our privacy policy .

Toptal Developers

  • Algorithm Developers
  • Angular Developers
  • AWS Developers
  • Azure Developers
  • Big Data Architects
  • Blockchain Developers
  • Business Intelligence Developers
  • C Developers
  • Computer Vision Developers
  • Django Developers
  • Docker Developers
  • Elixir Developers
  • Go Engineers
  • GraphQL Developers
  • Jenkins Developers
  • Kotlin Developers
  • Kubernetes Developers
  • Machine Learning Engineers
  • Magento Developers
  • .NET Developers
  • R Developers
  • React Native Developers
  • Ruby on Rails Developers
  • Salesforce Developers
  • SQL Developers
  • Tableau Developers
  • Unreal Engine Developers
  • Xamarin Developers
  • View More Freelance Developers

Join the Toptal ® community.

More than 1 year has passed since last update.

dynamic constant assignment ruby on rails

【Ruby】dynamic constant assignmentというエラー

ページタイトルをhelperを使って動的に表示するために、以下のコードを書いた。

ここで、BASE_TITLEは定数であるため、UPPER_SNAKE_CASEで定義している。 またrubyにおける定数は再定義ができるソフトな(破壊的変更が可能な)代物なので、再定義ができないようにfreezeメソッドを使って凍結しておいた。

実行した結果、 syntax errorとして以下のエラーが表示された

メソッドの外で定数を定義する。

どうやらrubyでは、メソッドの中で定数を定義できない仕様になっているらしい。

Register as a new user and use Qiita more conveniently

  • You get articles that match your needs
  • You can efficiently read back useful information
  • You can use dark theme

IMAGES

  1. Active Record Relationships: A Ruby on Rails Cheat Sheet

    dynamic constant assignment ruby on rails

  2. Software Engineering: Ruby on Rails database using static lookup tables

    dynamic constant assignment ruby on rails

  3. Displaying version of Ruby & Rails for your Rails application

    dynamic constant assignment ruby on rails

  4. Ruby on Rails Routing

    dynamic constant assignment ruby on rails

  5. Ruby on Rails Examples to Consider

    dynamic constant assignment ruby on rails

  6. GitHub

    dynamic constant assignment ruby on rails

VIDEO

  1. S246: Ruby on Rails and the Spring Framework is a bad idea

  2. Hunter assignment Ruby game boys double attitude

  3. Hunter assignment Ruby game

  4. Julie Bisaillon Freediving Promo

  5. Hunter assignment Ruby game boys attitude

  6. Custom Button Actions in Ruby on Rails 7 for Beginners

COMMENTS

  1. ruby

    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:

  2. Dynamic constant assignment in Ruby

    It gives multiple "dynamic constant assignment" errors: ... How do I get the current absolute URL in Ruby on Rails? Hot Network Questions If 'provincial' is the adjective for provinces what is the adjective form of 'dominions'?

  3. Everything You Need to Know About Ruby Constants

    Ruby Constant: A type of variable that starts with an uppercase letter & shows a warning if you try to change it. ... def the_method ABC = 1 end # "dynamic constant assignment" So just define your constants outside methods, typically we want to have constant definitions at the top of your class so they are clearly visible. ... In Rails, there ...

  4. Autoloading and Reloading Constants

    Module#autoload provides a lazy way to load constants that is fully integrated with the Ruby constant lookup algorithms, dynamic constant API, etc. It is quite transparent. Rails internals make extensive use of it to defer as much work as possible from the boot process. But constant autoloading in Rails is not implemented with Module#autoload.

  5. dynamic constant assignment

    I have a constant set up like that : ALL_LOCALES => {"it"=>"Italian", "fr"=>"Français", "de"=>"Deutsch", "en- GB"=>"English (UK)", "es"=>"Español (España)", "pt-PT ...

  6. Dynamic constant assignment

    What is constant about a variable that changes everytime the locale changes? And if you have multiple users with different locales, potentially changes with every request? Given how changeable it is, why do you want to confuse the future maintainer by implying it is constant when it isn't.

  7. Using structs in ruby on rails gives dynamic constant assignment

    Ruby on Rails is a popular web development framework that utilizes the Ruby programming language. One of the key features of Ruby on Rails is the use of structs, which are a way to define custom data structures. However, sometimes when using structs in Ruby on Rails, you may encounter a "dynamic constant assignment" syntax […]

  8. Dynamic constants

    I'm looking to define dynamic classes, and in order to get them to play nicely with Rails I need them to behaving like a constantly defiend class. foo = Class.new. Won't work AFAIK because. foo.class == Class. If the new class is defined to a constant however it will work. Foo = Class.new. So far the only way I know of to do this is to use eval.

  9. What is "dynamic constant assignment"

    You can only assign a contant value (or expression) to it, once. That's not true. You can assign a value to a constant more than once, even if ruby will issue a warning: irb: 001> A = 1 1 irb: 002> A = 2 (irb):2: warning: already initialized constant A 2. I guess that the 'dynamic constant assignment' means that you can assing to a ...

  10. Dynamic Constant Assignment

    Props for the effort - that actually was a lot of code. I you are tired of the various puts, you can always do: alias e puts. Or something like that.

  11. Render partial yields "dynamic constant assignment"

    Don't start your partial names with a capital letter. rails creates a local variable for the object corresponding to the partial and local variables can't start with a capital letter Fred 11175 (-- --) May 29, 2008, 3:27pm

  12. Ruby constants

    How to define a Ruby constant. Constants begin with an uppercase letter. Example : 1. 2. 3. Boiling = 100 # valid BOILING = 100 # valid boiling = 100 # invalid. Constants defined within a class or module can be directly accessed from the inside. Those defined outside a class or module can still be accessed globally.

  13. Autoloading and Reloading Constants (Classic Mode)

    1 Introduction. This guide documents autoloading in classic mode, which is the traditional one. If you'd like to read about zeitwerk mode instead, the new one in Rails 6, please check Autoloading and Reloading Constants (Zeitwerk Mode). Ruby on Rails allows applications to be written as if their code was preloaded.

  14. Dynamic constant assignment Ruby

    Dynamic constant assignment Ruby [duplicate] Ask Question Asked 9 years, 4 months ago. ... dynamic constant assignment Console_Screen = Screen.new ^ typechallenge.rb:90: dynamic constant assignment Typing_Test = Test.new ... How do I get the current absolute URL in Ruby on Rails? 984. Why is it bad style to `rescue Exception => e` in Ruby?

  15. Mastering Variables and Constants in Ruby: The Beauty of Flexibility

    Ruby, a dynamic, object-oriented programming language, is known for its convenience and simplicity.One of the features that make Ruby so special is the way it treats variables and constants. In this article, we will delve into the depths of this language to understand how Ruby handles these essential elements and how you can elegantly use them in your own projects.

  16. Help on error: dynamic constant assignment

    ksruby wrote: Local variables must start with lowercase. Otherwise Ruby interprets them as a constant. So how do you create a local constant? James

  17. Metaprogramming: Writing in Ruby with... Ruby

    This is basic stuff in Ruby, but there is much more happening behind this code which we need to understand before we proceed further. It is worth pointing out that the class Developer itself is actually an object. In Ruby everything is an object, including classes. Since Developer is an instance, it is an instance of class Class. Here is how ...

  18. 【Ruby】dynamic constant assignmentというエラー #Ruby

    またrubyにおける定数は再定義ができるソフトな(破壊的変更が可能な)代物なので、再定義ができないようにfreezeメソッドを使って凍結しておいた。. 実行した結果、. syntax errorとして以下のエラーが表示された. dynamic constant assignment. BASE_TITLE = "title ...

  19. Understanding SOLID Principles for Ruby on Rails Development

    The SOLID principles are a set of five design guidelines that can help developers achieve this goal. When applied to Ruby on Rails development, these principles can lead to cleaner, more efficient code. Let's delve into each of these principles and see how they can be applied in a Ruby on Rails context. S: Single Responsibility Principle (SRP)

  20. Dynamic constants

    I'm looking to define dynamic classes, and in order to get them to play nicely with Rails I need them to behaving like a constantly defiend class. foo = Class.new Won't work AFAIK because foo.class == Class If the new class is defined to a constant however it will work. Foo = Class.new So far the only way I know of to do this is to use eval. newclass = eval("Foo#{some_string} = Class.new ...

  21. Dynamic Constant Assignment error in Ruby

    My Python isn't entirely up to scratch, but I believe it's because python doesn't really have 'constants' in the same way Ruby does. You can assign things with names of upper or lower case and it shouldn't make a difference. In Ruby, an upper case assignment indicates a constant, which you can't change once it has been assigned. -