Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
class Library
attr_accessor :games
def initialize(games)
#games = games
end
end
How comes there is a colon infront of games?
Whenever I research what the : means I usually find articles where people say its a symbol, then give a very ambiguous definition of what a symbol is.
To keep it simple: symbols are nothing more than a name for a constant. The value is irrelevant, but only symbols with the same name share the same value:
Symbol objects represent names [...] inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods.
See Ruby docs on Symbol for more details.
The usual use cases for symbols include:
keys for hashes (hsh[:foo] 0 42; hsh[:foo] #=> 42)
method or variable names, since those types of objects are not first-class citizens of Ruby (there is a Method class representing a method, but that's something different)
Please note, that symbols won't be garbage collected, unlike strings. That means, you should avoid code like
key = :"oh-my-#{bar}" # like string interpolation
when bar is build from user (attacker) generated input.
In the case of attr_accessor, the parameter (:games in your case), creates an instance variable with the same name (#games) plus a setter and getter method (let l = Library.new, then the setter l.games=(val) and the getter l.games become available).
Instances of Symbol class. However it's mentioned and explained in all tutorials or beginner guides I've seen so far.
The colon indicates the variable is a symbol. Symbols are Strings, with one important difference, Symbols are immutable. Mutable objects can be changed after assignment while immutable objects can only be overwritten.
Related
In the "Well grounded Rubyist 2nd Edition", David Black states that (p.239):
The symbol table is just that: a symbol table. It’s not an object table. If you use an identifier for more than one purpose—say, as a local variable and also as a method name— the corresponding symbol will still only appear once in the symbol table
Then the author goes ahead and gives the following example:
>> Symbol.all_symbols.size
=> 3118
>> abc = 1
=> 1
>> Symbol.all_symbols.size
=> 3119
>> def abc; end
=> :abc
>> Symbol.all_symbols.size
=> 3119
My question is two-fold:
How is it possible to have the same identifier for more than one purpose!? - I understand that Ruby knows which one is which based on context but is this enough?
The symbol that was created in the example above, which identifier does it refer to? The local variable or the method name?
Great question.
Let's untangle this one by one.
"How is it possible to have the same identifier for more than one purpose!?"
"The symbol that was created, which identifier does it refer to?"
Let me first start with code that might look more familiar.
Obviously we can use the same string str to store two objects in two hashes
str = "max"
people[str] = Person.new
statistics[str] = 42
Now your example code does exactly the same
# pseudo-code
sym = :abc
locals[sym] = 1
methods[sym] = Method.new(...)
Internally Ruby represents everything using hashes
there is a hash with all classes
for each class there is a hash with all methods
for each instance there is a hash with all instance variables
for each method activation there is a hash with all local variables
et cetera
…
Symbols are used as keys into those hashes, and as such the same symbol can be used many times to map to many things in many hashes. Just the same way the code in your Rails app may use the same string as key in many different hash objects.
Now symbols are somewhat special. There is one and only one instance for :abc and Ruby uses a hash, yet another hash — the so-called symbol table — to map all symbols to an internal magic number. And then these magic numbers are used internally to refer to the symbol. I guess that is why the author of the book wrote "the symbols table is not an object table."
Mapping a string "abc" to these internal numbers is called "interning" and hence symbols are sometimes referred to as interned strings.
Fun fact, you can lookup these magic numbers yourself with :symbol.object_id and even infer from the order of numbers which symbols have been created first.
Hope that answers your question :)
I have not read the book, but the first two sentences seem to refer to the same questions you ask:
The symbol table is just that: a symbol table. It’s not an object table.
In other words - symbols can be names for identifiers, but they are not identifiers, nor do they have 1:1 mapping with identifiers directly (without context).
foo is an identifier. :foo is just the name of that identifier.
How is it possible to have two people named John? It's just a name, not an id.
Which person does the name John refer to? Depends on the context. In this case - the variable.
I can go into further details on how the actual resolution happens in the language if this question wasn't conceptual in nature.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have just been watching this video ion Symbols in Ruby. In the video it seems to say that assigning a variable creates a symbol of the same name and points it the the respective object in the assignment.
I understand the difference between as String and a Symbol, in that strings create unique objects every time where as Symbols always reference the same object. However I am struggling to understand the difference between a Variable and a Symbol of the same name.
For example, how is:
var = 55
Different from:
:var = 55
In Ruby, you can store data in a Hash object... a Hash object is a collection of key value pairs
star_info = {:name = > "Johnny Depp", :birth_year => 1963, :birth_country = "USA" }
So the hash star_info has information about a movie star. It's stored as keys (I'm using symbols but I didn't have to; it's common and efficient to do so) and values (the value related to this particular movie star for the related key).
To get the movie star's name I could do...
p star_info[:name]
=> "Johnny Depp"
So although the symbol doesn't actually "store" data intrinsically as a variable would, it can be used as a pointer to data stored in some Hash object.
To successfully retrieve data related to a symbol, you have to have BOTH the symbol (the key) and the Hash object (the object where the key/value pairs are stored).
EDIT
Just reviewed the video you referenced, it's a good video as far as it goes... what you might find confusing is that he refers to variables as "internal symbols" and it's not helpful to have a conceptual model based on that. Symbols are representations... the symbol :west represents the concept :west and does not point to any other object.
Symbol, as everything in Ruby, is an object, so it is a structure in the memory having methods, properties. And the variable is a pointer (reference) to the object - it stores the memory address, where the object lives.
So this var = :something is a valid syntax, it creates a Symbol instance :something and the variable var referencing (pointing) to this instance.
Learn more on symbols and reference on this article: Ruby for Admins: Strings and Symbols.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am making a dating simulator. One of the first things I need is to keep track of the way characters feel about each other. In this sim, anyone can date anyone else, and there are two variables for relationship (one for love and one for friendship).
So I thought the easiest way to do this would be for each character to have a separate class that kept track of how they felt about everyone else. Below is one such sample class. I also thought that the easiest way to keep track of where points should be added was by giving each character a hash that pointed to their own variable, and then using a swap function to trade targets with the person they are speaking to.
However, I am getting an error message.
class HRelatStatus
def initialize
{#target=> #hrelat}
#krelat =[10, 10]
#arelat =[9, 4]
#srelat =[13, 11]
#jrelat =[12, 1]
#brelat =[5, 5]
#hrelat=[0, 0]
end
def dataaccess
attr_accessor :target, :krelat, :arelat, :srelat, :jrelat, :brelat, :hrelat
end
def makehappy
#target[0] = #target[0]+1
end
end
hfeels=HRelatStatus.new
puts #krelat.class
puts #krelat[1]
hfeels.makehappy
puts #target[0]
When I try to run this, #krelat comes back as a Nil class. And when I try to run the makehappy method (or any method, really) I get the error message undefined method '[]' for nil class.
How do I stop my instance variables from being nil classes? How can I sucessfully make methods that will add to one variable in the array for a specific character? And does anyone have a better idea for how I can specify who to target?
You are saying:
hfeels=HRelatStatus.new
puts #krelat.class
But there is no such thing as #krelat in this context. What you are after is the krelat instance variable inside your instance, i.e. hfeels.krelat.
(Of course, that won't work either because you've hidden your accessor generators inside an instance method.)
The first thing you actually need to do is learn how Ruby (or really, variable scope in any language) works.
#krelat outside of the class is totally unrelated to #krelat inside the class.
The makehappy method won't work because { #target => #hrelat } doesn't do anything in Ruby (well, it creates a hash with a nil key pointing to a nil value and then discards that hash. Ie. effectively nothing.
This code is a total mess, learn Ruby first. Buy "Programming Ruby" and read it.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
Browsing the ruleby source code, I noticed that they were calling Container(:and), which is something I rarely see. In fact, the only other place I've seen it is in the fabrication gem
A quick look showed that Container subclasses Array, and a quick hop into Pry showed that Array(:anything) #=> [:anything].
Another quick look at the ruby documentation for Array doesn't shed much light on to this question.
What method is being called by Array(), where is it documented, how can one define a method like this, and is it considered "bad form" in ruby?
For your first question, the answer is that it makes an array of its parameters.
For your second, I have no clue, but it's simple enough.
For your third, here it is: In Ruby, defining a global method with the same name as the class is considered good form only when used to construct or convert from object of that type of a more fundamental type. You should not define this method unless you are creating some sort of low type. You could define this for some class like BigInt128 but you shouldn't for ObscureOrSpecializedType678. There is also a design for these methods.
If the data that you are passed is of the returned type, return it. If the data is of a directly related type, perform obvious conversions (Fixnum to BigInt128). If the data passed in can be converted and is somewhat related (String to Fixnum) convert it (this conversion is usually only for String). If the data can not be converted, throw an exception. You should NEVER return a "magic value".
The other use of this method is to create a semi-literal syntax for non-literal types. The best examples of this are Rational() and Complex(). These functions, in addition to doing conversions, allow you to create rations and complex numbers in a more natural way (Rational(1, 2) vs. Rational.new(1, 2)). If there is a certain argument list that is simpler to the literal representation of a type, you would define a Classname() method.
For the most part, these methods are only part of the core language, and unless you are making a class like BigInt128 or FancyString or NaturalNumber, you should not define these methods.
From what I know the defined of these are:
Array(*args) -- Returns arguments as an array
Complex(real, complex) -- Create a complex number with given real and complex parts
Float(arg) -- Returns arg converted to a float (takes things like strings too)
Integer(arg) -- Same as Float(), but converts to an integer(floats are truncated)
Rational(numerator, denominator=1) -- Creates a Rational number with the given parts
String(arg) -- Converts argument to string by calling to_s
Also, some classes define [] as a class method, which is used for more complex initialization from basic data types (usual initialization only, not conversion) such as Hash[].
I don't know if it is really it, but made some tests with iurb and I guess it is only a helper funcion to create a new Array.
Given I have this class
class MyClass
def initialize(arg)
puts "Initialized with #{arg.to_s}"
end
end
then I can define a helper function like
def MyClass(arg)
MyClass.new(arg)
end
and here you go
irb(main):009:0> MyClass(1)
Initialized with 1
=> #<MyClass:0x4770e10>
uhhhh, since you're in Pry why not ask Pry to show you the documentation?!?!
[25] (pry) main: 0> show-doc Array
From: object.c in Ruby Core (C Method):
Number of lines: 4
Owner: Kernel
Visibility: private
Signature: Array(arg1)
Returns arg as an Array. First tries to call
arg.to_ary, then arg.to_a.
Array(1..5) #=> [1, 2, 3, 4, 5]
[26] (pry) main: 0> show-method Array
From: object.c in Ruby Core (C Method):
Number of lines: 5
Owner: Kernel
Visibility: private
static VALUE
rb_f_array(VALUE obj, VALUE arg)
{
return rb_Array(arg);
}
[27] (pry) main: 0>
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.