Forum: Ruby on Rails The similarities and differences between 'name' & :name

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Bruce B. (Guest)
on 2005-12-13 07:24
(Received via mailing list)
Oh knowledgeable ones:

I know that :this is a symbol (how was that for terseness without
unintelligibility?). I know that 'this' is a string.  They seem to be
largely interchangeable but are they?

If I start with 'they are the same' please tell me where that
statement is false.

Thanks in advance,

bruce
Bruce B. (Guest)
on 2005-12-13 07:39
(Received via mailing list)
I have decided to take the unusual step of replying to my own email.

There is a good clear explanation of the difference at this address

http://glu.ttono.us/articles/2005/08/19/understand...

If you are intrigued by the same question, this explanation is
beautifully clear.

bruce
Francois P. (Guest)
on 2005-12-13 09:51
(Received via mailing list)
I have a corporate client that wants me to develop an web application
for them to use within their intranet.

One of their requirements ,however, is that the app use microsoft
windows network indentification and authorization.

Is this something that will be possible to do with rails, has anyone
done this already?

regards,

Franc
Francois P. (Guest)
on 2005-12-13 10:09
(Received via mailing list)
Hi,

I've just had the idea to have a single document (with relevant links to
more specific explinations) with a step-by-step checklist of stuff to do
when creating a rails app so i can standardize on how i go about
developing new rails apps.
I'm hoping to include everything from setting up svn, configuring
switchtower, creating the database, editing config files, locking gem
versions down, writing tests, creating MVC, testing, setting up
webserver, deploying via switchtower. and all the nitty gritty stuff in
between.

I know there are individual pages in the wiki covering each of the above
to some degree in the wiki, but i'm really just looking to have a nice
checklist that I can use to drive my development/deployment.

if you have similar documents lying around that you use for yourself
please mail them to me, or if you have specific ideas of how one should
go about de(velop|ploy)ing post them here.

if i have missed the page in the wiki that has something like this
already, please point me towards it.

if there are any intrest, i'll draw up a wikipage with all the steps and
options and branches, in broad terms, that you'll probably go through to
get your apps live.

Regards,

Franc
Jan P. (Guest)
on 2005-12-13 10:36
(Received via mailing list)
Hi Francois,

"Active Directory" and "NTLM" would be the search terms that you should
combine with "rails" on Google and the mailing list archives.

Just as a startup pointer:
http://www.livejournal.com/community/rails_dev/1873.html

regards
Jan
CSN (Guest)
on 2005-12-13 12:12
(Received via mailing list)
That was one thing I've been wondering about. I had
assumed 'key'==:key. But that article doesn't explain
how symbols manage to be so much more efficient than
strings. For example:

> patient1 = { :ruby => "red" }
> patient2 = { :ruby => "programming" }
> patient1.each_key {|key| puts key.object_id.to_s}
3918094
> patient2.each_key {|key| puts key.object_id.to_s}
3918094

The same object id? How is that accomplished, and
where are the values really stored? Magic?

csn


--- Bruce B. <removed_email_address@domain.invalid> wrote:

> I have decided to take the unusual step of replying
> to my own email.
>
> There is a good clear explanation of the difference
> at this address
>
>
http://glu.ttono.us/articles/2005/08/19/understand...
>
> > If I start with 'they are the same' please tell me
> > removed_email_address@domain.invalid
> >
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
> _______________________________________________
> Rails mailing list
> removed_email_address@domain.invalid
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Kev J. (Guest)
on 2005-12-13 12:58
(Received via mailing list)
CSN wrote:

>>
>where are the values really stored? Magic?
>
>csn
>
>
You must realize that it's just the symbol :ruby that shares the same
object_id, not the string value (which must of course be different)

With symbols, the interpreter creates one memory address (or something
similar), binds a value to it and then just uses the memory address in
all the places where that value occurs.  if instead You used a string as
a key in a Hash, the intrepeter will have to store each string
individually in a different memory location, using up much more space.
So it's the keys of the hash that are more efficient as symbols, not the
values themselves

if you know other languages it's a similar (but not exactly the same)
idea to a constant or in Java a static final String is much more
efficient to use than a normal string, but at the expense of never being
able to be changed (although in Java Strings are immutable, so when you
do "1" + "2" it actually creates 3 strings to finally produce "12")

Kev
Bothari (Guest)
on 2005-12-13 13:40
(Received via mailing list)
Francios,

I've started doing this at my day job, where I call them Cheat Sheets.
 The best way I've found to write them (and make them accurate) is to
actually _do_ all the steps and write them down.  However, I really
like the idea of using existing parts of the wiki, too.

If you've had a chance to hear Dave T. give his talk about
"Hearding Racehorses and Racing Sheep" he talks about what people need
to get things done.  Beginniners (sheep) need explicit instructions
without too much explaination because they get overwhelmed with all
the choices.  Experts don't want all the details, they just want a
vauge idea of the goal and the error message you're getting.  They've
probably done what you're doing, and they can answer your question
without wasting their time.

The point is that for beginners, you really need cheat sheets.  When
you realize that, you can wrie the document with the exact steps and
less chatter.  They'll understand the context once they see it work.
This concept has also helped me several times when approaching a
grouchy old expert that no one wants to deal with, but knows
everything about everything.

Good Luck,
Joe

On 12/13/05, Francois P. <removed_email_address@domain.invalid> wrote:
> between.
> already, please point me towards it.
> removed_email_address@domain.invalid
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


--
"For a new software system, the requirements will not be completely
known until after the users have used it."  Humphrey's Requirements
Uncertainty Principle.
rhubarb (Guest)
on 2005-12-13 15:05
Kev J. wrote:

>>
> You must realize that it's just the symbol :ruby that shares the same
> object_id, not the string value (which must of course be different)
>
> With symbols, the interpreter creates one memory address ...

Actually I've always had trouble finding a clear answer to the Symbol
question too. It's never made clear enough, not even in that admittedly
fairly clear explanatation linked to above.

I'm still not sure I know the true answer to "what is a symbol and how
is it different from a string", but I'm getting closer. And I think part
of the problem is that the symbols are used for different things.


1. Symbols as strings:

Firstly, as described in the rest of this thread, they're used where a
constant string might be used, in the interests of saving memory and
time.
This is often equated with "interning" strings in Java, whereby the
String class maintains a static pool of string objects that can be
reused when a given string value is commonly used.

The advantage - in both Ruby symbols and Java interned strings, is that
if you create 1000 of these things holding the same value, you only
create one object.

So in Ruby,
	a = "foo"
	b = "foo"

creates 2 string objects. Somewhere in memory are 2 different copies of
"f",  "o" and "o".
And a and b are really pointers to these two different memory locations.

Whereas

	a = :foo
	b = :foo

allocates a string - well actually a Symbol - object only once.
There's only one location with the "f" followed by the two "o"s, and a
and b both point to that same location.

(As a side note, it happens that in Java a = "foo"; b = "foo" version
would actually share the same object like the symbol version in Ruby.
That's because in this contrived example we're using string literals and
Java always interns literal Strings)

Now, if you're really _using_ strings, that is, if you are truly
manipulating strings - say, scraping web pages for information, adding
first and last names together, inserting punctuation, encoding html -
then real strings are what you want. You want a and b to be different
because you want to fiddle with a without messing with b.

But maybe you're just using strings as a sort of constant, as kind of
"marker" value. Say you have a method that takes an argument indicating
whether an mpeg movie should stop, play or pause.

	controlMovie("stop")

Now you're going to read that argument "stop" in your controlMovie
definition and stop playing. But you weren't really using "stop" as a
string. You're not going to modify it; you're not going to find the
index of "to" in it; you don't care how long it is. You're just using as
a marker. In some langauges (including Ruby) you might use a constant,
in some you might use an enum.
There's nothing really wrong with using a string - it just wastes
resources. Every time you call controlMovie("play") a new 4-character
string is allocated in memory. And every time you compare it in the
definition of controlMovie with, say

	if (s == "pause")

then you are wasting time comparing the strings character by character.

In this case, we tend to use a symbol.

	controlMovie(:stop)

	def controlMovie

	if (s == :stop) # compares the pointers - i.e. compares two integers -
very fast

For three reasons I would think (and I could be wrong here - I'm
somewhat of a 'rewbie'  - a ruby newbie) we use symbols:

a) It saves memory by not allocating the same string twice - as
discussed above
b) It saves time by not comparing character by character
c) It's become a Ruby idiom. That is, when you see the symbol, you know
right away that this is a sort of constant/enum/marker value.

I think c) is important - often symbols are used when the cost of using
a string instead would be neglible. But the symbol is just clearer.
Idiom is important in Ruby.



2. Symbols as names:

The second use of symbols is the most overlooked in these discussions:
symbols as names.
Most (all?) computer languages use symbols, and maintain a Symbol Table
to hold them.

Symbols are names. Names of variables, names of methods, names of
classes. In the examples I've displayed above, it was clear that :stop
and :foo were symbols. But actually, so were a, b and controlMovie.
(Well, sort of. Really a, b and controlMovie are names that cause
Symbols to be created and stored on the Symbol table. So given there is
a method called controlMovie, there is automatically a symbol
:controlMovie)

The Symbol Table holds a single Symbol for every name used in the
program. Even if the name is used for different things - local variables
in different methods say - there's only one Symbol for it in the global
table. (There'll be another table for each method mapping that symbol to
an memory address - but we're not talking about mapping here, we're just
talking about the holding of the Symbols themselves)

Compiled languages like C only use the Symbol Table at compile time and
discard it unless compiling with a debug flag. (Debuggers need to show
you the value of a variable given its name - so they need to use the
Symbol Table).

Ruby's interpreted, so it keeps its Symbol Table handy at all times. You
can find out what's on it at any given moment by calling
Symbol.all_symbols()

Note that this doesn't mean you can find the value. When you do a =
"foo", the symbol :a gets created - but you can't use that as the
"address of a" as you might use &a in the C language. It's just symbol.
And the global Symbol Table is really just a list of all the symbols
used in this execution of a Ruby program.

Every time Ruby sees a Symbol being used for the first time, a Symbol is
created and put on the table. The second time it sees that symbol it
finds it on the table.

This use of symbols can be important to the programmer. Those methods
that introspect Ruby generally deal with symbols. So, for example, the
Module method public_method_defined?(symbol) expects a symbol to be
passed in for the method name.
The Java equivalent Reflection method would take a String.

3. The confusion:

Here's why I think people get confused about Symbols. And this is
probably only one of the possible reasons.  I'm totally guessing here -
but I tend to find that software often works a certain way for
historical rather than logical reasons, and that the historical code -
it's history being generally hidden to the user - tends to be the most
confusing. I think that symbols have a history, and I'm guessing
(_totally_ guessing) it works like this:

i) Because Ruby is interpreted language, it has its Symbol Table around
at all times.

ii) Because Ruby has good natural introspection, and because its Symbol
Table is "around", it makes sense to use Symbols rather than strings for
describing those program elements that are really symbols anyway. It
makes sense to let programmers use Symbols.

iii) Because these symbols are easy to read like strings, yet are unique
throughout the execution of the Ruby program (because true symbols are)
- it make sense to use them as "consants" or marker strings.

In other words, it's the two different uses of symbols, and the fact
that one probably arose from the other, that makes them confusing.

Correct me if I'm wrong.
Bruce B. (Guest)
on 2005-12-13 15:43
(Received via mailing list)
Thanks Kev:

I enjoyed your explanation. I feel better because even though I am
still a little lost (I didn't think I was, but if you are then I am)
but at least I know which town I'm in.

bruce
Jason E. (Guest)
on 2005-12-13 15:46
(Received via mailing list)
Francois P. wrote:

> I have a corporate client that wants me to develop an web application
> for them to use within their intranet.
>
> One of their requirements ,however, is that the app use microsoft
> windows network indentification and authorization.
>
> Is this something that will be possible to do with rails, has anyone
> done this already?

Hello Francois,

If Active Directory is serving LDAP, then you can use ActiveLDAP for
user and password authentication. See
http://wiki.rubyonrails.com/rails/pages/ActiveLDAP

You might be able to query AD groups but as far as I know, the
priviledges must still be defined in Rails. I.e. group admin in AD gets
permission to edit users.

I'm not sure how to tie ActiveLDAP into one of the login generators,
though.

I hope this helps.

Sincerely,
Jason
Phillip H. (Guest)
on 2005-12-13 22:10
(Received via mailing list)
On 13/12/2005, at 11:11 PM, CSN wrote:

> 3918094
>
> The same object id? How is that accomplished, and
> where are the values really stored? Magic?

Don't think of symbols as special strings, think of them as a handy
programmer shortcut. Always remember that symbols are not strings,
and strings are not symbols. Symbols are only ever created
once. :thing will always be the same object and that object is
immutable, strings are created whenever you ask for one.

Use symbols when:
  * You're using them for referencing things inside your application.
Symbols never leave your application
  * You just need a name for a hash, you're never going to change the
name.

Use strings when
  * You're going to output or manipulate the string

If you want a better explanation read the pickaxe, it'll enlighten
you somewhat.

--
Phillip H.
removed_email_address@domain.invalid
Douglas L. (Guest)
on 2005-12-13 23:31
(Received via mailing list)
2005/12/13, CSN <removed_email_address@domain.invalid>:
>
No magic, though it might help with a simpler example.

First, I'm going to "create" three symbols, and see what IDs we get:

>> :symbol.object_id
=> 3053838
>> :symbol.object_id
=> 3053838
>> :symbol.object_id
=> 3053838

Hmm, all three have the same id. We didn't create three symbols, just
the one, which we can always get back using :symbol. The next time we
do :symbol, we'll get the same symbol object back.

Now we'll try the same thing using a string, note the object IDs:

>> "string".object_id
=> 23587468
>> "string".object_id
=> 23584816
>> "string".object_id
=> 23582164

This time they are all different! We've created three different
strings with different IDs. Each time we do "string", we create a new
string.

I can proove that the symbol is the same object by setting properties
on it. Here I am setting the instance variable @foo:

>> :symbol.instance_variables
=> []
>> :symbol.instance_variable_set(:@foo, 'bar')
=> "bar"
>> :symbol.instance_variables
=> ["@foo"]

If you try the same thing with "string" it won't work, because you'll
get a new string each time, without the instance variable set:

>> "string".instance_variables
=> []
>> "string".instance_variable_set(:@foo, 'bar')
=> "bar"
>> "string".instance_variables
=> []

hth,
Douglas
Douglas L. (Guest)
on 2005-12-13 23:49
(Received via mailing list)
2005/12/13, Bruce B. <removed_email_address@domain.invalid>:
> They seem to be largely interchangeable but are they?

If you load up interactive ruby, IRB, you can get a quick answer:

>> "foo" == :foo
=> false

So, they don't think that they are the same.

When can we use them interchangeably? One place, and you'll find it in
the Rails source for the HashWithIndifferentAccess. You can see the
whole class here:

http://dev.rubyonrails.org/browser/trunk/activesup...

But the bit we are interested in is this line:

42 	    def convert_key(key)
43 	      key.kind_of?(Symbol) ? key.to_s : key
44 	    end

So, what does that do?

Well, whenever a key is used with an indifferent hash (hash[:key]), it
gets run through convert_key. If the key is a Symbol, it is converted
into a string, otherwise we just use the key as given. Back to our
original example:

>> "foo" == :foo
=> false

But this is true:

>> "foo" == :foo.to_s
=> true

So that's where you can use them interchangeably :-)

hth,
Douglas
Peter F. (Guest)
on 2005-12-16 00:31
(Received via mailing list)
On 12/13/05, Bothari <removed_email_address@domain.invalid> wrote:
> to get things done.  Beginniners (sheep) need explicit instructions
> grouchy old expert that no one wants to deal with, but knows
> > when creating a rails app so i can standardize on how i go about
> >
> >
> --
> "For a new software system, the requirements will not be completely
> known until after the users have used it."  Humphrey's Requirements
> Uncertainty Principle.
> _______________________________________________
> Rails mailing list
> removed_email_address@domain.invalid
> http://lists.rubyonrails.org/mailman/listinfo/rails
>

Your cheat sheets sounds an awful lot like a new wiki page with the
"steps"
listed and the supporting documentation wikid.

What say you?

--
CSN (Guest)
on 2005-12-29 21:33
(Received via mailing list)
Found one place :key and 'key' aren't interchangable.

Controller:
  elements.each do |node|
    n = {:id=>node.id, :title=>node.title}
    @items<<n
  end

View:
  <% for item in @items %>
  <%= item[:id] %> <%= item[:title] %>
  <% end %>


Boths parts much use either both symbols or strings
for the keys. Using symbols in the controller and
strings in the view (and vice versa) won't work.

still confused :(
csn



--- Douglas L. <removed_email_address@domain.invalid> wrote:

> So, they don't think that they are the same.
>
> When can we use them interchangeably? One place, and
> you'll find it in
> the Rails source for the HashWithIndifferentAccess.
> You can see the
> whole class here:
>
>
http://dev.rubyonrails.org/browser/trunk/activesup...
> hash (hash[:key]), it
>
> http://lists.rubyonrails.org/mailman/listinfo/rails
>




__________________________________________
Yahoo! DSL ? Something to write home about.
Just $16.99/mo. or less.
dsl.yahoo.com
Ezra Z. (Guest)
on 2005-12-29 22:06
(Received via mailing list)
CSN-

	That is because you are building a plain old ruby hash in the n
variable. Plain old ruby hashes don't have the interchangeable
behavior. In rails there is a custom hash called
HashWithIndifferentAccess that can interchange :sybbols and "strings"
as keys. you are just constructing a plain hash that must have
either :symbols or "strings" as keys in order to behave correctly.

Cheers-
-Ezra

On Dec 29, 2005, at 11:33 AM, CSN wrote:

>   <% for item in @items %>
>
>>
>>
>> So, what does that do?
>> => false
>> _______________________________________________
> Just $16.99/mo. or less.
> dsl.yahoo.com
>
> _______________________________________________
> Rails mailing list
> removed_email_address@domain.invalid
> http://lists.rubyonrails.org/mailman/listinfo/rails
>

-Ezra Z.
Yakima Herald-Republic
WebMaster
http://yakimaherald.com
509-577-7732
removed_email_address@domain.invalid
Phillip H. (Guest)
on 2005-12-29 23:55
(Received via mailing list)
On 30/12/2005, at 8:33 AM, CSN wrote:

>   <% for item in @items %>
>   <%= item[:id] %> <%= item[:title] %>
>   <% end %>
>
>
> Boths parts much use either both symbols or strings
> for the keys. Using symbols in the controller and
> strings in the view (and vice versa) won't work.
>
> still confused :(

A symbol is not a string. A string is not a symbol. They are about as
equal as '5' and 5, they look similar but they are not the same.
Remember this and all will be well.

The root cause is that 'key'.hash and :key.hash are different,
'key'.hash computes a string hash, whereas :key.hash just gives you
the object ID. Rails cheats and uses 'HashWithIndifferentAccess' to
blur the issue. It's essentially a special hash subclass that
converts all symbol keys to strings before lookup (or the other way
around, it doesn't matter). Do not rely on this, Ruby hashes don't
work this way.

Personally I think HashWithIndifferentAccess is a mistake, but I'm
not maintaining rails.


--
Phillip H.
removed_email_address@domain.invalid
This topic is locked and can not be replied to.