Ruby on Rails: How do I set a variable to a constant, where part of the name of the constant can change?
Either use:
"User::#{arg2}".constantize
or
User.const_get(arg2)
How to assign variable's value to a constant?
The Ruby constants are expected to preserve the same value, it's a recommendation, not a must:
A Ruby constant is like a variable, except that its value is supposed to remain constant for the duration of the program. The Ruby interpreter does not actually enforce the constancy of constants, but it does issue a warning if a program changes the value of a constant.
In rails, where to put a constant (variable?) that changes based on the current date?
I think that here you can use Rails caching. Look here and here for more details and examples.
Basicaly, you can write to cache:
Rails.cache.write('date', Date.today)
and read:
Rails.cache.read('date')
You can use it in whole Rails application (models, views, controllers, ...).
You can store any object in cache. Default caching uses memory and is availble for single Rails instance, however you can use different cache storing method.
Can `merge!` change a CONST in Ruby?
I have a situation where
merge!
seems to modify the value of a CONST. Can this occur? How?
No, in general, methods cannot change variable bindings, regardless of whether those variables are local variables, instance variables, class variables, global variables, or constants. Variables aren't objects in Ruby, you can't call methods on them, you can't pass them as arguments to methods, ergo, you can't tell them to change themselves.
The exception to this are meta-programming methods like Binding#local_variable_set
, Object#instance_variable_set
, Module#class_variable_set
, or Module#const_set
.
What you can do, however, and what you are doing in this case, is tell the object the variable points to to change itself. The documentation for Hash#merge!
is unfortunately a bit unclear in that it does not explicitly mention that Hash#merge!
mutates its receiver.
This seems to confirm that, after running the
extract_features!
method, theFEATURE_DEFAULTS
CONST is changed. If I do not usemerge!
inextract_features!
, and usemerge
instead, then the CONST value does not change.
No, it only confirms that the state of the object FEATURE_DEFAULTS
points to changed, it doesn't say anything about whether the binding of FEATURE_DEFAULTS
, i.e. which object it points to, changed. You can confirm that the constant still points to the same object by looking at its object_id
.
Of course, constants can be re-assigned anyway, albeit triggering a warning.
Ruby on Rails: how do I set a variable where the variable being changed can change?
foo = "bar"
current_user.send("allow_#{foo}=", true)
EDIT:
what you're asking for in the comment is another thing. If you want to grab a constant, you should use for instance
role = "admin"
User.const_get(role)
Using a Variable Name as Attribute in Rails
If you want to assign to an attribute, you need the method name with the equal sign:
f.send("#{percent_field}=", 5)
Also, this:
rank_class = (klass.name).constantize
is equivalent to this:
rank_class = klass
Set a Ruby variable and never be able to change it again?
They are called constants. A constant in Ruby is defined by a UPPER_CASE
name.
VARIABLE = "foo"
It is worth to mention that, technically, in Ruby there is no way to prevent a variable to be changed. In fact, if you try to re-assign a value to a constant you will get a warning, not an error.
➜ ~ irb
2.1.5 :001 > VARIABLE = "foo"
=> "foo"
2.1.5 :002 > VARIABLE = "bar"
(irb):2: warning: already initialized constant VARIABLE
(irb):1: warning: previous definition of VARIABLE was here
=> "bar"
It's also worth to note that using constants will warn you if you try to replace the value of the constant, but not if you change the constant value in place.
2.1.5 :001 > VARIABLE = "foo"
=> "foo"
2.1.5 :002 > VARIABLE.upcase!
=> "FOO"
2.1.5 :003 > VARIABLE
=> "FOO"
In order to prevent changes to the value referenced by the constant, you can freeze the value once assigned.
2.1.5 :001 > VARIABLE = "foo".freeze
=> "foo"
2.1.5 :002 > VARIABLE.upcase!
RuntimeError: can't modify frozen String
from (irb):2:in `upcase!'
from (irb):2
from /Users/weppos/.rvm/rubies/ruby-2.1.5/bin/irb:11:in `<main>'
2.1.5 :003 > VARIABLE
=> "foo"
Here's an example inside a class.
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT
# => "foo"
Correct use of concern's constants
I just came across the same bug, when trying to implement concerns.
The guide I was following also but the Constant in the included block and seemed to have no error. But my log threw me exactly the same error you have.
After some trial and error, I just removed the Constant from the block and put it outside, like:
module UserInstance
extend ActiveSupport::Concern
included do
end
ACTIVE = 'active'
end
This way I could still access the Constant, but didn't get anymore errors. I'm not 100% sure that this is the right way, but it worked and I couldn't find any errors, so I will go with it.
I would like to now if this works for you too!
Constants and scope in loops with Ruby
There seems to be no strict equivalent to Java's final in ruby. However, you could use remove_const
(which is a private method in Module
) to get rid of the constant (and the warnings) at the end of the loop:
5.times do |x|
XPI = x * Math::PI;
puts x;
Object.instance_eval{ remove_const :XPI };
# this would work, too: Object.send(:remove_const, :XPI);
end
Related Topics
Sublime Text 2 Doesn't Save Built SASS File
How to Make an Infowindow Automatically Display as Open with Google-Maps-For-Rails
How to Overwrite the '{ }' Object
How to Return the Number of Devise Users Currently Logged In
What Is the Fully Qualified Name of a Model in Ruby on Rails
Loaderror - Cannot Open Shared Object File - File Is Present, But It Says No Such File
Why Sinatra Request Takes Em Thread
Rails - How to Add Contacts to Sendgrid Marketing Campaigns via API
My Classes Can't Use Shoes Methods Like Para
Check If String Is Repetition of an Unknown Substring
Ruby: How to Process a CSV File with "Bad Commas"
Differencebetween Def Func(Var) and Def Func=(Var)
Can Ruby Tell If It Is Called from an Interactive Shell or Cron
How to Display Error Messages in a Multi-Model Form with Transaction