i am trying to declare a dynamic array like below.
<% Product_in_Stock_array = [] %>
but it is not working giving syntax error.
You have to be a bit more specific.
The code you have is most likely an erb template file.
This is actually a valid erb template
ERB.new('<% Product_in_Stock_array = [] %>').result
Your syntax error has to be somewhere else.
Additionally you most likely want to create a variable not a constant. In Ruby names starting with capital letter are constants (written in UpperCamelCase or UPPER_CASE most often), normal variables are written in camel_case.
Related
I am trying to write a script in ruby which involves converting a string to Class Names. Since I am using pure ruby I cannot use .constantize.
I have tried using Object.const_get('String') but not sure why it is throwing a uninitialized constant String (NameError)
I have require 'active_support' on the top of the file
The conventional way of assigning a name to an anonymous class is as follows.
bub = Class.new do
def b
'hi'
end
end
str = 'Bubba'
Object.const_set(str, bub)
Bubba.is_a?(Class)
#=> true
Bubba.new.b
#=> "hi"
Is that what you want to do? If so, as you see, you need to use Module#const_set.
Do you try to use const_get only for a class or it is under a namespace like ModuleA::ModuleB::ClassName?
Also converting a string to a class name makes a new class or assigns the value to it?
I am asking these questions because the answer will affect the method you have to use. Maybe const_set instead of const_get is the correct approach, I don't know.
From the comments you gave it looks like 'String' is just an example and not the value that you literally pass to const_get. The actual value apparently is 'Assignment', is this correct?
When you execute Object.const_get('Assignment') and you receive the uninitialized constant error it indicates that at this point the class Assignment has not been loaded yet.
When you are using Rails then a lot of autoloading takes place if the files are in the right folder and the classes follow the naming conventions. Since you are running a "standalone" ruby script, autoloading does not take place and you will need to load the file yourself.
Adding a line like
require_relative "somepath/assignment"
should work. somepath needs to be adapted to the directory/file layout you have. It will load the file and execute the ruby code in that file.
If assignment.rb defines something like
class Assignment
end
Then the const_get will work.
That being said: what is your exact use case for this? Why do you need to dynamically find classes? Also Note that this opens up your app to (an unlikely) potential security issues if you let user input define what classes are loaded.
In ERB or HAML, I need to be able to evaluate one function, or a different one, based on the output of a conditional, while using the same HTML block for either one.
In HAML, it would like something like this:
- is_a = #thing.is_a?
= (is_a ? f.method_a : f.method_b) arg_1, |block_arg1| do
#thing
.blah
.inner-thing
= block_arg1.some_method
Notice how, on line 2 of my pseudocode, I am trying to evaluate either one function, or the other, based upon a conditional. But I need pass the same arguments to either, especially since I don't want to have to re-type the DO block.
Maybe I could avoid that problem ("I don't want to re-type...") by making that DO block a named function? How does one turn a HAML or ERB block into a named Ruby function?
I'm using Ruby-on-Rails 4. Not that it matters; this looks like more of a ruby syntax question than a framework question.
You seem to be looking for #send
- is_a = #thing.is_a?
= f.send(is_a ? :method_a : :method_b, arg_1) do |block_arg|
(...)
I have spent already a long deal of time trying to figure out how to do this, I have also investigated but I have not found the right approach to it...?
basically I am trying to do something like the following:
types = ['type1','type2']
classes = ['class1','class2']
classes.each do |class|
types.each do |type|
template "/files/filename.txt" do
source "source_file.erb"
owner "root"
group "root"
mode "0440"
variables({
:pri_areas => node['area']['#{type}']['#{class}'],
:rev_areas => node['area']['#{type}']['#{class}']
})
end
end
end
Obviously I got all the attributes already defined so everything looks all right from that front..
I still cannot manage to get a loop with arrays like that withing the variables?
Maybe another different approach?
Any ideas/help?
Thanks very much.
Your code has some issues which you need to fix before it will properly work.
At first, class is a reserved keyword in Ruby and thus can't be used as a variable name. You should use another one, e.g. klass.
Secondly, class (or klass) as well as type are already strings inside your loop. Thus you don't need to attempt string interpolation. You can directly use this:
variables({
:pri_areas => node['area'][type][klass],
:rev_areas => node['area'][type][klass]
})
The reason why your string interpolation didn't work is that ruby knows two different kinds of String literals: ones with " and ones with '. The difference is that the ones delimited with ' do not allow string interpolation and generally do not interpret anything inside then as something else than the literal written string. Only in Strings delimited by ", you can perform string interpolation like "#{foo}" and use escape sequences like \n.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In Ruby, can you perform string interpolation on data read from a file?
I need to loop through a few 'li' elements:
for i in 1..5
Xpaths.getPath("location","elements")
end
Then, all xpaths are in an external file, so the value of such 'elements' variable is as follows:
{
"location":
{
"elements" :"//ul[#id='locations']/li[#{i}]/a"
}
}
The elements variable is read as a string, and [#{i}] is not replaced with values such as [1]. Is there a way to define a specific part of a string in an external file as a variable?
If I understand your question correctly, you have some external data file in JSON format, whose structure has certain fields as XPath strings on which you would like to perform Ruby string interpolation.
The short answer is that yes, you can do this directly using, say Kernel#eval. There are also other options such as using erb. A solution using the simple "eval" route might look like this:
xpaths = JSON.load(File.read('my-xpaths.json'))
(1..5).each do |i|
xpath = eval(xpaths['location']['elements'].to_json)
# => "//ul[#id='locations']/li[1]/a"
end
Of course, using "eval" is fraught with peril since you are essentially executing code from another source, so there are many precautions you must take to ensure safety. A better approach might involve doing a simple regular expression replacement so that you can constrain the interpolation on the XPath item:
xpaths['location']['elements'] # => "//ul[#id='locations']/li[__INDEX__]/a"
xpath = xpaths['location']['elements'].gsub(/__INDEX__/, i.to_s)
# => "//ul[#id='locations']/li[1]/a"
See also this related question: In Ruby, can you perform string interpolation on data read from a file?
I'm new to the Ruby and Ruby on Rails world. I've read some guides, but i've some trouble with the following syntax.
I think that the usage of :condition syntax is used in Ruby to define a class attribute with some kind of accessor, like:
class Sample
attr_accessor :condition
end
that implicitly declares the getter and setter for the "condition" property.
While i was looking at some Rails sample code, i found the following examples that i don't fully understand.
For example:
#post = Post.find(params[:id])
Why it's accessing the id attribute with this syntax, instead of:
#post = Post.find(params[id])
Or, for example:
#posts = Post.find(:all)
Is :all a constant here? If not, what does this code really means? If yes, why the following is not used:
#posts = Post.find(ALL)
Thanks
A colon before text indicates a symbol in Ruby. A symbol is kind of like a constant, but it's almost as though a symbol receives a unique value (that you don't care about) as its constant value.
When used as a hash index, symbols are almost (but not exactly) the same as using strings.
Also, you can read "all" from :all by calling to_s on the symbol. If you had a constant variable ALL, there would be no way to determine that it meant "all" other than looking up its value. This is also why you can use symbols as arguments to meta-methods like attr_accessor, attr_reader, and the like.
You might want to read up on Ruby symbols.
:all is a symbol. Symbols are Ruby's version of interned strings. You can think of it like this: There is an invisible global table called symbols which has String keys and Fixnum values. Any string can be converted into a symbol by calling .to_sym, which looks for the string in the table. If the string is already in the table, it returns the the Fixnum, otherwise, it enters it into the table and returns the next Fixnum. Because of this, symbols are treated at run-time like Fixnums: comparison time is constant (in C parlance, comparisons of symbols can be done with == instead of strcmp)
You can verify this by looking at the object_id of objects; when two thing's object_ids are the same, they're both pointing at the same object.
You can see that you can convert two strings to symbols, and they'll both have the same object id:
"all".to_sym.object_id == "all".to_sym.object_id #=> true
"all".to_sym.object_id == :all.object_id #=> true
But the converse is not true: (each call to Symbol#to_s will produce a brand new string)
:all.to_s.object_id == :all.to_s.object_id #=> false
Don't look at symbols as a way of saving memory. Look at them as indicating that the string ought to be immutable. 13 Ways of Looking at a Ruby Symbol gives a variety of ways of looking at a symbol.
To use a metaphor: symbols are for multiple-choice tests, strings are for essay questions.
This has nothing to do with Rails, it's just Ruby's Symbols. :all is a symbol which is effectively just a basic string.