I was reading through this article, because I am currently learning Capistrano.
I found this line on this page:
set :deploy_to, '/var/www/my_app_name'
I am not sure if this is a Ruby feature or a Capistrano feature.
I checked Ruby for sets but it only has the datastructure Set(s).
I don't think this is a datastructure like set.
This looks like a key-value pair or a hash table where the value(s) right after the keyword set is the key and the string/value after the , is the value of the key-value pair/hash table (field).
Is this a Ruby feature or a Capistrano feature? What is the name of this particular feature?
This is a Ruby feature. It is called a "message send". If you are familiar with other languages, they call it a "subroutine call", "method call", "function call", "function application", "procedure call", or similar.
More precisely, it is a receiverless message send to the implicit receiver self with two arguments, the first being the symbol literal :deploy_to, the second being the string literal '/var/www/my_app_name'.
Related
This question applies in particular to Ruby 1.9 and 2.1, where String literals can not be frozen automatically. In particular I am refering to this article, which suggests to freeze strings, so that repeated evaluation of the code does not create a new String object every time, which among other advantages is said to make the program perform better. As a concrete example, this article proposes the expression
("%09d".freeze % id).scan(/\d{3}/).join("/".freeze)
I want to use this concept in our project, and for testing purpose, I tried the following code:
3.times { x="abc".freeze; puts x.object_id }
In Ruby 2.3, this prints the same object ID every time. In JRuby 1.7, which corresponds on the language level to Ruby 1.9, it prints three different object IDs, although I have explicitly frozen the string.
Could somebody explain the reason for this, and how to use freeze properly in this situation?
In particular I am refering to this article, which suggests to freeze strings, so that repeated evaluation of the code does not create a new String object every time
That is not what Object#freeze does. As the name implies, it "freezes" the object, i.e. it disallows any further modification to the object's internal state. There is nothing in the documentation that even remotely suggests that Object#freeze performs some sort of de-duplication or interning.
You may be thinking of String#-#, but this does not exist in Ruby 2.1. It was only added in Ruby 2.3, and actually had different semantics then:
Ruby 2.3–2.4: returns self if self is already frozen, otherwise returns self.dup.freeze, i.e. a frozen duplicate of the string:
-str → str (frozen)
If the string is frozen, then return the string itself.
If the string is not frozen, then duplicate the string freeze it and return it.
Ruby 2.5+: returns self if self is already frozen, otherwise returns a frozen version of the string that is de-duplicated (i.e. it may be looked up in a cache of existing frozen strings and the existing version returned):
-str → str (frozen)
Returns a frozen, possibly pre-existing copy of the string.
The string will be deduplicated as long as it is not tainted, or has any instance variables set on it.
So, the article you linked to is wrong on three counts:
De-duplication is only performed for strings, not arbitrary objects.
De-duplication is not performed by freeze.
De-duplication is only performed by String#-# starting in Ruby 2.5.
There is also a fourth claim that is wrong in that article, although we can't really blame the author for that since the article is from 2016 and the decision was only changed in 2019: Ruby 3.0 will not have immutable string literals by default.
The one thing that is correct in that article is that the # frozen_string_literal: true pragma (or the corresponding command line option --enable-frozen-string-literal) will not only freeze all static string literals, it will also de-duplicate them.
Symbols are immutable objects, are lightweight strings, and are not garbage-collectable. I don't understand how they work in a Rails route or path. For instance, in:
get '/patients/:id', to: 'patients#show'
:id will be replaced by a number, and we get something like /patitent/1. However :id = 1 is not allowed. How is this assignment performed?
The value '/patients/:id' is a normal Ruby string, and although the :id part looks like a symbol, it is not.
When Rails parses the string, it uses the colon to identify a parameter name in the path. When it sets the parameter from receiveing a request like GET /patients/1, it does not attempt to alter the symbol value, but does something like the following
params[:id] = '1'
Note I'm not 100% certain that is doesn't just use the string "id" as the key here. But either way you can see it does not alter any symbol value, but just uses the name of the symbol so you know which key it will be stored under in the params Hash
The similarity between ':id' as part of the URL parameter definition and for when you use the Symbol literal :id might be confusing, but is a design choice shared used in Rack path handling engine so most Ruby web frameworks use the same style.
I am an extremely new person to Ruby and Chef. I have been trying to wrap my head around the syntax and do some research, but I am sure as you all know unless one knows the terminology, it is hard to find what you are looking for.
I have read up on Ruby code blocks, but the Chef code blocks still confuse me. I see something like this for example:
log "a debug string" do
level :debug
end
Which adds "a debug string" to the log. From what I have seen though, it seems to me like it should be represented as:
log do |message|
#some logic
end
Chef refers to these as resources. Can someone please help explain the syntax difference and give me some terminology from which I can start to educate myself with?
If you come from another language (not Ruby), this syntax might seem very strange. Let's break down things.
When calling a method with parameters, in most cases the parentheses are optional:
foo(bar) is equivalent to foo bar
foo(bar, baz) is equivalent to foo bar, baz
A Ruby block of code can be wrapped in curly braces ({}) or inside a do..end block and can be passed to a method as its last parameters (but note that there's no comma and if you're using parentheses it goes after them. Some examples:
foo(bar) { # code here }
foo(bar) do
# code here
end
foo bar do
# code here
end
foo do
# code here
end
In some cases, code blocks can receive parameters, but in Chef the resources' blocks never do. Just for reference, the syntax for that is:
foo(bar) do |baz, qux|
baz + qux
end
Specifically about Chef resources, their syntax is usually:
resource_type(name) do
attribute1 value1
attribute2 value2
end
This means that, when you say:
log "a debug string" do
level :debug
end
you're actually creating a log resource whose name attribute is set to "a debug string". It can later be referred to (in other resources, for example) using log[a debug string].
AFAIK, the name attribute is mandatory for every Chef resource type as it's what makes it unique, and allows you to, among other things, call actions on it after it has been declared.
Side note: The ruby block is usually optional for a Chef resource. If you do something like:
directory "/some/path"
Chef will compile that resource using its default attributes (among which is action :create), and try to create the named directory using those.
The do ... end here is not a usual ruby block statement.
It's a implementation of DSL (Domain Specific Language).
Here's a nice explanation [1]:
there is the concept of an internal DSL, which uses the syntax of an
exіsting language, a host language, such as Ruby. The means of the
language are used to build constructs resembling a distinct language.
The, already mentioned, Rake uses this to make code like this
possible:
task :codeGen do
# do the code generation
end
Hope that answer your question.
[1] : http://www.infoq.com/news/2007/06/dsl-or-not
I heard that everything in ruby is object. I replied in an interview that a variable is an object, and the interviewer said NO. Anybody know the truth?
"In ruby, everything is an object" is basically true.
But more accurately, I would say that any value that can be assigned to a variable or returned from a method is an object. Is a variable an object? Not really. A variable is simply a name of an object (also known as a "pointer") that allows you locate it in memory and do stuff with it.
shajin = Person.new()
In this snippet, we have a variable shajin, which points to an object (an instance of the person class). The variable is simply the identifier for an object, but is not the object itself.
I think it was a trick question. Ultimately object orientation is feature for humans to understand complex programs, but computers are not object oriented themselves. Drill down enough layers and objects cease to exist in any language.
So perhaps it's more fair to say: "In ruby, everything important is an object".
Why not go directly to the source? The Ruby Language Specification couldn't be more clear and obvious (emphasis added by me):
6.2 Variables
6.2.1 General description
A variable is denoted by a name, and refers to an object, which is called the value of the variable.
A variable itself is not an object.
http://www.techotopia.com/index.php/Understanding_Ruby_Variables
"A variable in Ruby is just a label for a container.
A variable could contain almost anything - a string, an array, a hash.
A variable name may only contain lowercase letters, numbers, and underscores.
A variable name should ideally make sense in the context of your program."
"We'll begin with the fact that Ruby is a completelyobject-orientated language. Every value is an object (...)."(The Ruby Programming Language, Flanagan & Matsumoto, page 2).
Note this book, co-authored by the language creator, does not state "everything is an object".
a = 1
1 is an object, 'a' is a reference to the 1 object. If 'a' was an object on it's own, it would have an object_id of it's own. But:
1.object_id #=> 3
a.object_id #=> 3
Also, methods are not really objects (but you can turn them into objects if needed).
#Alex Wayne and #Jörg W Mittag answears are correct, but I would like to add that "not everything" important is an object. Like method and block are not objects, but can be converted to objects, with method method and proc respectively.
I have just started using Ruby and I am reading "Programming Ruby 1.9 - The Pragmatic Programmer's Guide". I came across something called symbols, but as a PHP developer I don't understand what they do and what they are good for.
Can anyone help me out with this?
It's useful to think of symbols in terms of "the thing called." In other words, :banana is referring to "the thing called banana." They're used extensively in Ruby, mostly as Hash (associative array) keys.
They really are similar to strings, but behind the scenes, very different. One key difference is that only one of a particular symbol exists in memory. So if you refer to :banana 10 times in your code, only one instance of :banana is created and they all refer to that one. This also implies they're immutable.
Symbols are similar to string literals in the sense that share the same memory space, but it is important to remark they are not string equivalents.
In Ruby, when you type "this" and "this" you're using two different memory locations; by using symbols you'll use only one name during the program execution. So if you type :this in several places in your program, you'll be using only one.
From Symbol doc:
Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods. The same Symbol object will be created for a given name or string for the duration of a program‘s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
So, you basically use it where you want to treat a string as a constant.
For instance, it is very common to use it with the attr_accessor method, to define getter/setter for an attribute.
class Person
attr_accessor :name
end
p = Person.new
p.name= "Oscar"
But this would do the same:
class DontDoThis
attr_accessor( "name" )
end
ddt = DontDoThis.new
ddt.name= "Dont do it"
Think of a Symbol as a either:
A method name that you plan to use later
A constant / enumeration that you want to store and compare against
For example:
s = "FooBar"
length = s.send(:length)
>>> 6
#AboutRuby has a good answer, using the terms "the thing called".
:banana is referring to "the thing
called banana."
He notes that you can refer to :banana many times in the code and its the same object-- even in different scopes or off in some weird library. :banana is the thing called banana, whatever that might mean when you use it.
They are used as
keys to arrays, so you look up :banana you only have one entry. In most languages if these are Strings you run the risk of having multiple Strings in memory with the text "banana" and not having the code detect they are the same
method/proc names. Most people are familiar with how C distinguishes a method from its call with parentheses: my_method vs. my_method(). In Ruby, since parentheses are optional, these both indicate a call to that method. The symbol, however, is convenient to use as a standin for methods (even though there really is no relationship between a symbol and a method).
enums (and other constants). Since they don't change they exhibit many of the properties of these features from other languages.