Forum: Ruby Demystifying Symbols.

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.
12271b6df73fe29930d65586be5a4a70?d=identicon&s=25 Dave Howell (Guest)
on 2006-01-05 08:26
(Received via mailing list)
I was actually doing really well until the strange discussion involving
throwing constants into the mix showed up, so I'm ignoring that.

Steve's Newby Guide was excellent, if overly-complicated.

Extremely useful item (I think from Gregory, but I'm not sure):

	attr_accessor "liquids", "solids"

as effective and functional as

	attr_accessor :liquids, :solids



So Steve, or anybody, I've learned that I can :mysymbol.to_i and I get
an integer back. OK, I give up. What possible use do I have for this
zany parlor trick? I'll hazard a guess that, as a "normal" programmer,
not doing system-level stuff, not extending Ruby, not trying to do
something dense and clever and incomprehensible...I don't.

In fact, somebody correct me if I'm wrong, but I could actually never
use a Symbol in a single line of Ruby code and I'd still be able to get
everything done that I might reasonably want to.


Anyway, I'm quite confident I know what a Symbol is now. It's an
immutable string.

Stop!! Put your geek away! I didn't say it was a String. It's a string.
It's a Merriam-Webster "string1" 5b(2) 'series of like objects (e.g.
characters, bits, words)'. It's just a series of characters cemented
together, bless its little stable self. What Ruby calls a String is
actually some kind of pandimensional quasi-magic method-possessing
self-modifying Object, and not an ordinary string at all.

Note that the neologism
	:symbol is to "symbol" as 1 is to "1"
makes not one iota of sense unless one already understands all the
complex ramifications of those quote marks. And given the extra magic
powers of double quotes vs. single quotes, well, ick.

A couple of people have tried to advance the idea that a Symbol is a
name. I think that's a terrible mistake. On the one hand, here in the
real world, people will say something like "Dave is a boy's name," but
what that sentence *really* means is "The word 'dave' is normally used
only as a name for males."

For me, :dave doesn't become a name until I decide what it's the name
*of*. :dave is just a boring old string, and when I say
	attr_accessor :dave
what I'm actually saying is "Dear routine/module/function named
'attr_accessor,' please create a couple of new methods for my
Class/Module/whatever. Use that string I sent you as the name of one
which will return the value of a variable also named that, and use it
yet again to build a setter method." That'll get me a method named
"dave", a method named "dave=", and, hmm. I don't know if "dave=" will
work if I don't explicitly set @dave to a value at some point, although
I think it will. I'd have to check that to find out.

Anyway, that's not the important point. Nor is the potential
"efficiency" of Symbols vs. Strings. Good grief, have you people looked
at the millisecond differences that I've been seeing thrown around? We
beginners couldn't care less; we just want it to not make lots of
errors when it runs, or doesn't run.


What I've learned:
	A Symbol is just a modest, simple string. It's optional; I could
always use a String instead. It's good for  naming things that are
'inside' my program, and that won't need to be modified, input, output,
or generally fiddled with.

or

A Symbol is a non-variable variable (aka a constant) that always and
only contains its own name.


Seriously, as a newbie, that last sentence is all I need to know. And,
quite honestly, probably all I'll *ever* need to know about Symbols.
Fd22ee3cfc7dac283ce8e451af324f7d?d=identicon&s=25 Chad Perrin (Guest)
on 2006-01-05 09:14
(Received via mailing list)
On Thu, Jan 05, 2006 at 04:25:31PM +0900, Dave Howell wrote:
>
> So Steve, or anybody, I've learned that I can :mysymbol.to_i and I get
> an integer back. OK, I give up. What possible use do I have for this
> zany parlor trick? I'll hazard a guess that, as a "normal" programmer,
> not doing system-level stuff, not extending Ruby, not trying to do
> something dense and clever and incomprehensible...I don't.

The integer value can be regarded as a side effect of the way symbols
are managed.  They're stored as values in a hash table with the integers
as keys, basically.  It's the atomic number-like value of the symbol,
and the "it has always been there" behavior[1] of it when first defined,
that the language feature is after -- not the integers associated with
symbols in the hash table.  If you find a good use for the .to_i
behavior, though, have at it.

At least, that's my understanding.


>
> In fact, somebody correct me if I'm wrong, but I could actually never
> use a Symbol in a single line of Ruby code and I'd still be able to get
> everything done that I might reasonably want to.

Symbols are useful for metaprogramming techniques, and can be used as
well for some minor performance increases.  For most of the programming
people do, however, they're far from necessary.

Note:  My comment about symbols being useful for metaprogramming
techniques is based on my understanding of symbols in a Lisp context,
not a Ruby context.  I'm still trying to get a handle on how analogous
the two are to each other -- a lot, clearly, but the devil's in the
details (so to speak).  I'm nothing like a Ruby expert, and there's a
lot of context to learn before I can be sure about those details.


>
> Stop!! Put your geek away! I didn't say it was a String. It's a string.
> It's a Merriam-Webster "string1" 5b(2) 'series of like objects (e.g.
> characters, bits, words)'. It's just a series of characters cemented
> together, bless its little stable self. What Ruby calls a String is
> actually some kind of pandimensional quasi-magic method-possessing
> self-modifying Object, and not an ordinary string at all.
>
> Note that the neologism
> 	:symbol is to "symbol" as 1 is to "1"

For purposes of my analogy to that effect a few days ago, that could as
easily have been single quotes as double quotes, in case there's any
confusion on the matter.  My point was the relative characteristics of a
Ruby string literal as compared with numbers and symbols.


>
> For me, :dave doesn't become a name until I decide what it's the name
> *of*. :dave is just a boring old string, and when I say
> 	attr_accessor :dave

This makes me want to draw analogies between Ruby symbols and spoken
language phonemes, which while interesting and in some respects accurate
would probably not be helpful to many people.


>
> A Symbol is a non-variable variable (aka a constant) that always and
> only contains its own name.
>
>
> Seriously, as a newbie, that last sentence is all I need to know. And,
> quite honestly, probably all I'll *ever* need to know about Symbols.

That depends on just how advanced your programming gets.  Programs that
write themselves are nothing to sneeze at.  One of these days, I'll be
at a point where I can actually take advantage of that sort of thing --
but I'm not there yet.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

This sig for rent:  a Signify v1.14 production from
http://www.debian.org/
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-01-05 13:57
(Received via mailing list)
Hi --

On Thu, 5 Jan 2006, Dave Howell wrote:

> 	A Symbol is just a modest, simple string. It's optional; I could
> always use a String instead.

That depends.  If you're calling a method that insists on a Symbol
argument, you have to use a Symbol.  Many methods are written to
accept either, though.

> It's good for  naming things that are 'inside' my program, and that
> won't need to be modified, input, output, or generally fiddled with.

Since the "is a string" thing has resonances with classes and
hierarchies and so on, it's also possibly helpful to think of it as:
Ruby has two ways of representing *text*: String and Symbol.  Or
something like that.

> or
>
> A Symbol is a non-variable variable (aka a constant) that always and only
> contains its own name.

Well, Ruby has variables and constants, and symbols aren't either of
them :-)  I guess they're constant, informally, but they're not
constants, as defined by the language.  I wouldn't call them variables
in any sense.


David

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
Fe57662c550fb3cce44c398ddf2dd706?d=identicon&s=25 itsme213 (Guest)
on 2006-01-05 17:44
(Received via mailing list)
Yet another try ...

A symbol is an object with a string name. No two symbols (with different
object_id) can have the same name string.

The literal
  :x
evaluates to a symbol with name "x", creating the symbol if necessary.


"Dave Howell" <groups@grandfenwick.net> wrote in message
news:cfe9ee0530a44c3082704317b922535c@grandfenwick.net...
Fd22ee3cfc7dac283ce8e451af324f7d?d=identicon&s=25 Chad Perrin (Guest)
on 2006-01-05 17:44
(Received via mailing list)
On Thu, Jan 05, 2006 at 09:54:35PM +0900, dblack@wobblini.net wrote:
>
> Well, Ruby has variables and constants, and symbols aren't either of
> them :-)  I guess they're constant, informally, but they're not
> constants, as defined by the language.  I wouldn't call them variables
> in any sense.

I guess that, if you want to compare them to "variables" (things that
you create, define, and change at whim) and "constants" (things that you
create, define, and -- hopefully -- never change), you could think of
symbols as "forevers": from the point of view of the programmer, you
never really create or define the things, you just discover them waiting
there for you, already in the form they will always have.  Heh.

There are data types, and there are data archetypes, I suppose.

That's just another broken analogy, though, and ultimately I keep
wanting to come back to some technical details related to internal hash
table behavior.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

This sig for rent:  a Signify v1.14 production from
http://www.debian.org/
1b62a85b59ccab03b84ee5ec378f75b4?d=identicon&s=25 Steve Litt (Guest)
on 2006-01-05 21:57
(Received via mailing list)
On Thursday 05 January 2006 02:25 am, Dave Howell wrote:
>
> 	attr_accessor :liquids, :solids

Yeah, that was quite a breakthrough for me too. I coded it to prove it
to
myself, and from that moment on I found that I knew when to use Symbols,
and
what I could accomplish by using them.

>
> So Steve, or anybody, I've learned that I can :mysymbol.to_i and I get
> an integer back. OK, I give up. What possible use do I have for this
> zany parlor trick? I'll hazard a guess that, as a "normal" programmer,
> not doing system-level stuff, not extending Ruby, not trying to do
> something dense and clever and incomprehensible...I don't.

Hi Dave,

I personally know of no use, in *my* application as opposed to Ruby
internals,
for the integer representation of a symbol.

>
> In fact, somebody correct me if I'm wrong, but I could actually never
> use a Symbol in a single line of Ruby code and I'd still be able to get
> everything done that I might reasonably want to.

Except for giving up symbols' memory advantages and (probably slight)
performance advantages, that's my understanding also.
> self-modifying Object, and not an ordinary string at all.
I don't think it would hurt to think of it as an immutable string (not a
String), in your own personal life. However, that probably would not go
over
well on a mailing list :-)


>
> Note that the neologism
>
> 	:symbol is to "symbol" as 1 is to "1"
>
> makes not one iota of sense unless one already understands all the
> complex ramifications of those quote marks. And given the extra magic
> powers of double quotes vs. single quotes, well, ick.

I never understood that analogy.

[clip]

> A Symbol is a non-variable variable (aka a constant) that always and
> only contains its own name.

That's an interesting and concise statement. I'll have to think about
that.

SteveT

Steve Litt
http://www.troubleshooters.com
slitt@troubleshooters.com
1b62a85b59ccab03b84ee5ec378f75b4?d=identicon&s=25 Steve Litt (Guest)
on 2006-01-05 21:57
(Received via mailing list)
On Thursday 05 January 2006 03:13 am, Chad Perrin wrote:
> and the "it has always been there" behavior[1] of it when first defined,
> that the language feature is after -- not the integers associated with
> symbols in the hash table.  If you find a good use for the .to_i
> behavior, though, have at it.
>
> At least, that's my understanding.

Internals question: Curious -- why don't they hash with the object id
instead?

SteveT

Steve Litt
http://www.troubleshooters.com
slitt@troubleshooters.com
1b62a85b59ccab03b84ee5ec378f75b4?d=identicon&s=25 Steve Litt (Guest)
on 2006-01-05 22:12
(Received via mailing list)
On Thursday 05 January 2006 03:55 pm, Steve Litt wrote:
> > as keys, basically.  It's the atomic number-like value of the symbol,
> > and the "it has always been there" behavior[1] of it when first defined,
> > that the language feature is after -- not the integers associated with
> > symbols in the hash table.  If you find a good use for the .to_i
> > behavior, though, have at it.
> >
> > At least, that's my understanding.
>
> Internals question: Curious -- why don't they hash with the object id
> instead?

Oh never mind -- a more careful reading of Evan's internals explanation
makes
it clear.

SteveT

Steve Litt
http://www.troubleshooters.com
slitt@troubleshooters.com
10d4acbfdaccb4eee687a428ca00a5d8?d=identicon&s=25 Jim Weirich (weirich)
on 2006-01-05 22:46
Dave Howell wrote:
[...]
> A Symbol is a non-variable variable (aka a constant) that always and
> only contains its own name.

Heh.  That reminds me of the quote:

  The problem with programming is that
  variables don't and constants aren't."

Perhaps the word you are looking for is "literal".  I.e. the sequence of
characters (':', 'x', 'y', 'z') is the literal representation of the
symbol :xyz.  (Just as you would say the sequence of characters ('1',
'2', '3') is the literal presentation of the number 123).

--
-- Jim Weirich
2dc2228d8db84b46bdd834b0515a26a1?d=identicon&s=25 Lyndon Samson (Guest)
on 2006-01-06 00:46
(Received via mailing list)
>
> I personally know of no use, in *my* application as opposed to Ruby
> internals,
> for the integer representation of a symbol.



How about logging method names in a human readable manner using id2name
?

     method_missing(id, *args)

       id: method symbol
       *args: method arguments
12271b6df73fe29930d65586be5a4a70?d=identicon&s=25 Dave Howell (Guest)
on 2006-01-06 15:42
(Received via mailing list)
On Jan 5, 2006, at 12:54, Steve Litt wrote:

>
> I personally know of no use, in *my* application as opposed to Ruby
> internals,
> for the integer representation of a symbol.

Exactly. So if I'm going to try explaining Symbols to somebody who's
still trying to learn Ruby, I would completely omit any mention of the
fact you could .to_i a Symbol.

>> In fact, somebody correct me if I'm wrong, but I could actually never
>> use a Symbol in a single line of Ruby code and I'd still be able to
>> get
>> everything done that I might reasonably want to.
>
> Except for giving up symbols' memory advantages and (probably slight)
> performance advantages, that's my understanding also.

I'm a newby; I'm not to the point that I care about memory advantages.
I have a gigabyte to burn. Performance advantages appear to be nearly
indetectable. Long before Symbols make a difference, I probably ought
to learn many other far more relevant programming tricks to get more
speed.

> I don't think it would hurt to think of it as an immutable string (not
> a
> String), in your own personal life. However, that probably would not
> go over
> well on a mailing list :-)

Yes, well, the fact that this mailing list was full of the most
horrific dis-explanations of Symbols is one of the things that prompted
me to *not* keep my thoughts to myself.


> [clip]
>
>> A Symbol is a non-variable variable (aka a constant) that always and
>> only contains its own name.
>
> That's an interesting and concise statement. I'll have to think about
> that.

Somebody else suggested thinking of them as "forevers," which is pretty
cute.

A variable is a box. You can put a sign on the box, like "current_user"
or "amountPaid," and then put something in the box, put something else
in, and on and on. (Yes, in Ruby one actually puts references in the
box, not things. That is also a layer of complication inappropriate in
an explanation to a newbie, although it can't be put off for long.)

A constant is a wooden crate. You take something, build the crate
around it, then stick the sign on the outside. Put a watermelon in a
crate. Label it "oranges" if you like, but you can't put something else
in once you've built it.

A symbol is a crate with no label, but a clear cover. What you see is
what you get; the label is also the contents.


To restate the one-liner above:

A Symbol is an unalterable (*) that always and only contains its own
name.

Damn. I can't find any word besides "variable" to go in that spot.
"Container" is the functional description, and in programming, the
first kind of container you meet (in every language I know) is called a
variable, unless you learned Assembly first, and then it'd be
"register." I can't support "literal," since as a programming term, I
think it's quite obscure, which means I have to default to the general
English meaning, and it's not remotely literal in that sense.
Otherwise, I'd be able to sit down on a :chair. :)




P. S. With duck-typing as a Virtue in Rubyville, when am I ever going
to be presented with a method that won't accept a String as well as a
Symbol? Would there ever be a reason besides "bad programming" to be
that restrictive?


P. P. S. The "contains itself" aspect of Symbols reminds me of Rexx. In
Rexx, you can just use a variable without declaring it first, like
Ruby. Unlike Ruby, a "new" Rexx variable doesn't contain "nil". It's
initialized to its own name as a string. This would occasionally result
in the most *peculiar* error messages.
10d4acbfdaccb4eee687a428ca00a5d8?d=identicon&s=25 Jim Weirich (weirich)
on 2006-01-06 16:21
Dave Howell wrote:
> A variable is a box.

Hmmm ... see http://onestepback.org/index.cgi/Tech/Ruby/Shoeboxes.rdoc
for an alternate view.  I think the mental model of "boxes" as variables
doesn't work so well for Ruby.
82e62c756d89bc6fa0a0a2d7f2b1e617?d=identicon&s=25 Ross Bamford (Guest)
on 2006-01-06 17:48
(Received via mailing list)
On Fri, 06 Jan 2006 14:40:36 -0000, Dave Howell
<groups@grandfenwick.net>
wrote:

> P. S. With duck-typing as a Virtue in Rubyville, when am I ever going to
> be presented with a method that won't accept a String as well as a
> Symbol? Would there ever be a reason besides "bad programming" to be
> that restrictive?
>

Here's one:

	f = File.read(:"/etc/passwd")

	TypeError: can't convert Symbol into String
       	  from (irb):1:in `read'
	        from (irb):1

I guess it doesn't always 'make sense', and that it's just about not
bothering to coerce arguments to strings when that's the case.
B464ff27d7d3b0750a7bfe2717c49d2d?d=identicon&s=25 Chris Pine (Guest)
on 2006-01-07 04:58
(Received via mailing list)
On 1/5/06, Dave Howell <groups@grandfenwick.net> wrote:
> Note that the neologism
>         :symbol is to "symbol" as 1 is to "1"
> makes not one iota of sense unless one already understands all the
> complex ramifications of those quote marks.

This is why writing a decent tutorial is so hard.  Unless you really
talk to lots and lots of newbies, it's so easy to say totally useless
(well, useless in this context) things like this.

(Don't get me wrong:  I actually found it a delightful analogy!
Brilliant, in fact!  But I've been using symbols happily for years.
An analogy like this feels more like an inside joke than an
explanation.  :)

Chris
30a69d3e9ddb45dda39df00ca36a2eeb?d=identicon&s=25 Andrew McGuinness (Guest)
on 2006-01-07 15:26
(Received via mailing list)
Steve Litt wrote:
>>
>>as effective and functional as
>>
>>	attr_accessor :liquids, :solids
>
>

That's true, but only because attr_accessor can convert the Strings it
is passed to Symbols.  Internally, it's using Symbols.

>
Pretty much true.

The point is that Symbols exist in pretty much any language - they're
part of the normal process of parsing a program.  Any C compiler will
contain a definition of a type very like Symbol, and will use it for
indexing variables, functions and so on.  It doesn't make it into the
compiled program, though.

In Ruby, you can access the data structures created by the interpreter,
and it is natural to do so via the Symbol type it uses in them.  It is
not essential - it can all be implicit as with
 >> attr_accessor "liquids"
but the symbols exist, so why hide them from the programmer?

As to why you would want to use Symbol#to_i, there is basically one
reason for using it - as an array index.

def initialize; @values_array = []; end
def get_value( sym )
   @values_array[sym.to_i]
end
def set_value( sym, obj )
   @values_array[sym.to_i] = obj
end

That's only an optimisation over

def initialize; @values_map = {}; end
def get_value( str )
   @values_map[str]
end
def set_value( str, obj )
   @values_map[str] = obj
end

but it is an optimisation, and potentially a significant one, which is
why Symbols are used internally instead of strings in the first place.

Of course, if you wanted to do the above, and symbols didn't exist, you
could implement them yourself in 30 lines.  Again, Symbol is not there
because you need it - it's there because Ruby needs it, and you can use
it if you want.

class Cymbal
  @@byname = Hash.new
  @@nexti = 0

  def initialize( name )
   # not thread-safe - needs a mutex.
   @name = name
   @c_id = @@nexti
   @@nexti+=1
   @@byname[name] = self
  end

  def Cymbal.get( name )
   @@byname[ name ] || new( name )
  end

  def Cymbal.all_cymbals
   @@byname.values
  end

  def to_s ; @name ; end

  def to_i ; @c_id ; end

  private_class_method :new
end

The only difference between

cym1 = :Gas

and

cym2 = Cymbal.get("Gas")

is that the Symbol object :Gas is created as ruby parses the cym1 line,
but the Cymbal object is only created when ruby executes the cym2 line.
  This doesn't change the real semantics, though you can prove it by
playing with Symbol#all_symbols:

s1 = Symbol.all_symbols
if nil
:aardvark
end
s2 = Symbol.all_symbols
s2 - s1
=> [:aardvark, :s2]
Ec9233451f7c6ba37a83388b87a1f565?d=identicon&s=25 Gavin Kistner (Guest)
on 2006-01-07 18:15
(Received via mailing list)
On Jan 6, 2006, at 8:21 AM, Jim Weirich wrote:
> Dave Howell wrote:
>> A variable is a box.
>
> Hmmm ... see http://onestepback.org/index.cgi/Tech/Ruby/Shoeboxes.rdoc
> for an alternate view.  I think the mental model of "boxes" as
> variables
> doesn't work so well for Ruby.

Good point in your article - shoeboxes (or pigeonholes, as I
originally learned variables) are bad metaphors in a dynamically-
typed language.

Saying "bound" or "named" is right, but doesn't provide the same
visual mental model for beginners.

I like to explain it that variables are nametags that you hang on
things.

Assignment places a nametag on an object.
	person = 'Gavin'
	# Create a new box with the letters 'Gavin' in it;
	# hang on it nametag with 'person' scrawled on it

	me = person
	# Find the box with the 'person' nametag on it,
	# hang another nametag on it with 'me' scrawled thereon

	person = nil
	# Take the person nametag off the box,
	# and put it in the big black hole of tags without boxes

	me = nil
	# Do the same thing with the me nametag

Periodically, the Cosmic Janitor comes through with his rolling
garbage can. Any boxes that don't have name tags get thrown away,
leaving more room on the floor for you.

This metaphor makes it a little bit confusing explaining Arrays and
Hashes to new users of a dynamic language. At that point, I usually
ditch the nametag metaphor and start using fishing line that goes
between the nametag and the boxes. Arrays, then, are boxes with a
bunch of nails on them, with 0..n drawn on the heads. The fishing
line gets tied between a nail and a certain box, and the Janitor's
broom sweeps away anything that isn't tied to something else.

The benefit of the fishing line example is that it also helps with
scope. When I'm standing in one spot of the room, I can only see the
nametags on the floor near me, even though the fishing line on them
runs over to another box.
12271b6df73fe29930d65586be5a4a70?d=identicon&s=25 Dave Howell (Guest)
on 2006-01-07 23:20
(Received via mailing list)
On Jan 6, 2006, at 8:48, Ross Bamford wrote:

>
> 	f = File.read(:"/etc/passwd")
>
> 	TypeError: can't convert Symbol into String

Hmm. But that's the opposite of what I said. I'm not too dismayed if
something says "no, no, I don't want a Symbol. I want an honest-to-gosh
String." It's if it says "No, a String is unacceptable. I only take
Symbols" that I'd be really perplexed.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-01-07 23:41
(Received via mailing list)
Hi --

On Sun, 8 Jan 2006, Dave Howell wrote:

>>>
> that I'd be really perplexed.
A number of methods in the various Rails libraries only work with
symbol arguments.  For example, you cannot do:

   SomeModel.find("all")

or

   class SomeModel < ActiveRecord::Base
     has_many "others"
   end


David

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
Fd22ee3cfc7dac283ce8e451af324f7d?d=identicon&s=25 Chad Perrin (Guest)
on 2006-01-08 00:53
(Received via mailing list)
On Sat, Jan 07, 2006 at 12:57:21PM +0900, Chris Pine wrote:
> (Don't get me wrong:  I actually found it a delightful analogy!
> Brilliant, in fact!  But I've been using symbols happily for years.
> An analogy like this feels more like an inside joke than an
> explanation.  :)

I tend to assume one knows a little something about strings and variable
assignments and arithmetic operators and integers before one gets around
to learning symbols.  As such, it's probably not quite that useless.

At least, that's what I'd guess would be the case if you're learning in
anything approaching a structured manner, from tutorials, books,
classes, howtos, or whatever.  Maybe a mailing list doesn't count.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

This sig for rent:  a Signify v1.14 production from
http://www.debian.org/
12271b6df73fe29930d65586be5a4a70?d=identicon&s=25 Dave Howell (Guest)
on 2006-01-08 01:41
(Received via mailing list)
On Jan 6, 2006, at 7:21, Jim Weirich wrote:

> Dave Howell wrote:
>> A variable is a box.
>
> Hmmm ... see http://onestepback.org/index.cgi/Tech/Ruby/Shoeboxes.rdoc
> for an alternate view.  I think the mental model of "boxes" as
> variables
> doesn't work so well for Ruby.

Oh, I definitely agree. But again, my explanation is specifically for
Ruby newbies and beginners, especially those to whom "symbols" are new
territory. But I think explaining variables containing bound references
kind of has to follow the concept of variables as containers.

Gavin used fishing line to build a referencing metaphor. I've usually
used colored yarn, arrows, or maybe laser pointers on little tripods
when I'm trying to work it out in my head. :)

Reading Gavin's post and Jim's blog article dropped a new metaphor into
my head, one that, the more I test it out, the more I like it.




Assume that all your Objects are stored by Ruby in something resembling
an old post office mailbox room. Hundreds and hundreds of mailboxes,
all numbered, each with a key in the lock, waiting to be used. Ruby
stores strings and numbers and other Objects in these mailboxes. An
Object cannot exist unless it's in a box. Now, I *think* that Ruby
might let you access these containers by number. I know C will. But why
would you want to do that? Extremely confusing and inflexible.

	myName = "Dave"

And with that, Ruby builds a String, puts it in some mailbox, and hands
me a key with a tag that says "myName" on it. (The keychain tag, by the
way, is a classy metal tag with the writing engraved on it, not one of
those cheap plastic doodads with the paper you can slip out and write
on.)

	currentUser = myName

Ruby makes a key tag with "currentUser" on it, duplicates the myName
key, and puts it on the "currentUser" keychain.

	coolName = String.new(myName)

Ruby makes a new String just like the old one, puts it in a different
box, and puts the new different key on a chain with the tag "coolName."

	currentUser.replace("Sam")

Since "replace" replaces the contents of the String Object, Ruby takes
the key on currentUser, opens the box, takes out the String inside,
changes its contents to  "Sam", and puts it back. Obviously, if I now

	print myName

I'm going to get "Sam" because that's what's in that box now: a String
containing the characters "Sam".

	population = 486

I have a key with a tag that says "population" that opens a box
containing a FixNum(I think?) that contains the number 483.

	parkingSpaces = Array.new(40)

I have a keychain labeled "parkingSpaces." In the corresponding box is
a board with a bunch of nails numbered 0 through 39. The nails are
empty.

	parkingSpaces[3] = "VP Operations"

Now nail #3 has a key on it to a box that contains a String that
contains "VP Operations."

The difference between an Array and a Hash is, with an Array, the nails
are numbered, but you just hang plain keys on them, keys with no tags
attached. With a Hash, you have a bunch of nails (or maybe it's just a
bin) that are NOT numbered, but the keys all have tags.

Ruby knows which key opens which box because the keys have their box
number stamped on them.

	myName.object_id

But why would I care (most of the time) what box number my information
is in, when Ruby is so willing to go get my mail and bring it back for
me? :)

	TheAnswer = 42

Constants are like the kind of key chains you see for the bathroom at a
gas station or something. The keychain is extra big (that big Capital
Letter in the front that won't fit in your pocket), and once you put
the key on, you can't change it. You still get to decide what's written
on the tag, and you can put all sorts of things in the mailbox.



[As I started to write this next section, I realized that how this all
works is still very unclear to me. Let's see if I've figured it out . .
.]

	sillyNum = population + 14 / "5".to_i

Ruby make a new keychain tagged "sillyNum." There isn't a key on this
yet. That's what "nil" is; a keychain without a key.

Ruby takes my "population" keychain and opens that mailbox. She reaches
in to activate the enclosed FixNum's _plus_ method, which extends a
little chute labeled "put number here."

The next thing on that line, the number 14, is a Literal. The Pickaxe
book isn't really telling me exactly what happens here, but by playing
around in irb, the metaphor that seems to let me correctly predict
behavior is that Ruby manufactures a brand-new FixNum on the spot with
a 14 inside. Objects can't exist outside boxes, but I have no idea if
she extracts the value 14 from her new FixNum or if she whispers her
new FixNum's box number into the ear of the FixNum inside the first
box, but somehow the _plus_ gets whatever it wanted. It spits out a new
FixNum object that contains the value 500.

I think that Ruby puts this in a box and puts the key for this box on
the sillyNum keychain.

Now she activates the _divide_ method on the new Fixnum, and another
"put number here" chute opens.

Finally, she constructs a String object that contains the character
"5", and turns on the to_i method on the String, which pops out a
FixNum object containing the value 5? The FixNum 5 gets dropped into
the "put number here" chute, and the value of the sillyNum FixNum
becomes 100? Or maybe it also makes a new FixNum with a value of 500.
The keychain for the box containing the "5" String is thrown away. If
another new FixNum was created, then Ruby also takes the key for the
_500_ FixNum off the sillyNum keychain and throws the key away. She
puts the key for the _100_ FixNum on the keychain instead. I'm not sure
which, but the end result is effectively the same.

Of course, if she keeps putting things in boxes then throwing away the
keys, pretty soon there are a lot of Objects in boxes taking up space.
Ruby can always make new keys, but if there's no keychain with that key
available, then the mailbox's contents are inaccessible to the
programmer. When Ruby has a bit of spare time, or when too many of her
mailboxes have old Objects but no keys, she goes through and empties
out all the obsolete Objects, so she can reuse the mailboxes later.
This is called "garbage collection."


A Symbol is kind of like a Constant, except the only thing that the
mailbox can contain is a Symbol. A Symbol is kind of like a String
encased in acrylic. Also, Ruby engraves the key tag with exactly what's
inside the plastic. As a bonus, Symbols gets a "secret numeric
identity" engraved on the bottom.  (It's not the mailbox number.)

Symbols have almost none of the fancy accessories that come with
Strings. About all you can do with them is get a String containing the
name/contents of the Symbol, or get an Integer that contains the
Symbol's "secret numeric identity."

They differ from Strings in another way.

	print "Dave".object_id
	print "Dave".object_id
	print "Dave".object_id

results in something more or less like

	3945266
	6941506
	2937746

but

	print :Dave.object_id
	print :Dave.object_id
	print :Dave.object_id

looks more like

	8873230
	8873230
	8873230

That's because, unlike literals, Ruby doesn't throw away Symbol keys.
Every "Dave" results in a new String in a new box, and unless you
assign it to a variable (aka have Ruby put it on a keychain with a
tag), she throws the key away. But with a Symbol, Ruby *always* makes
the tag for the keychain when she makes the Symbol.




OK, that's enough of that. No metaphor is perfect, but duplicating keys
seems to work quite well across a remarkable amount of territory. So
what did I get functionally wrong (it doesn't really work quite like
that), and more importantly, what did I get effectively wrong (it
doesn't even *appear* to work like that). :)
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-01-08 02:44
(Received via mailing list)
I think the keychain analogy has some possibilities.

On Jan 7, 2006, at 7:40 PM, Dave Howell wrote:
> Ruby make a new keychain tagged "sillyNum." There isn't a key on
> this yet. That's what "nil" is; a keychain without a key.

No.  The new keychain has a single key on it to the mailbox
containing the object known as nil.

> sillyNum = population + 14 / "5".to_i

How about something a little simpler:

	a = b + 1

Ruby finds the mailbox that matches the key on the keychain labeled b.

There is a slot on the side of the object inside the mailbox.
Ruby makes a copy of the key on the :+ keychain and inserts it in the
slot.
Ruby makes a copy of the key on the 1 keychain and inserts it in the
slot.
Ruby then presses a button next to the slot.  The button is labeled
'send'.
Ruby waits a bit and then a new key clanks as it falls into a bin
labeled 'return value'.
Ruby attaches the new key to the keychain labeled a, discarding any
key that was there before.


Gary Wright
622fa8560c82dfaa59c91ec75efb0c19?d=identicon&s=25 Alex Combas (Guest)
on 2006-01-08 08:14
(Received via mailing list)
I'll be honest, as a rubynewbie I liked Jim's description of variables
better than any other description I've heard here so far,
and I'm going to go read his post on symbols and
see if that jives with me as well.

Jim's definition:
Variables are like dictionary definitions bound to an object.
VarA = VarB = ObjectZ

Explanation:
If you looked up the definition of VarA in our dictionary it would say
'ObjectZ'
and likewise if you looked up the definition for VarB in our
dictionary it would say 'ObjectZ'.

No, pointer, no container, no pigeon hole or shoebox.. just a strait
forward
term bound to a definition.

This maps nicely to the real world where you can look up the word 'house
cat'
in a dictionary and find that it maps to 'small domesticated
carnivorous mammal', the cat
doesn't 'point' to a carnivore in a pigeon hole, and it doesn't
'contain' a carnivore in a shoebox. 'House cat' is simply a term bound
to a definition in our dictionary.

In this dictionary more than one variable is permitted to be bound to
the same object:
small_dog = house_cat = 'small domesticated carnivorous mammal'

In a real dictionary terms are bound to descriptions, but in the ruby
dictionary
of variables we would say terms are bound to objects, this boils down
to exactly the same thing.

Grok?
2dc2228d8db84b46bdd834b0515a26a1?d=identicon&s=25 Lyndon Samson (Guest)
on 2006-01-08 08:26
(Received via mailing list)
>
> ...




In this dictionary more than one variable is permitted to be bound to
> the same object:
> small_dog = house_cat = 'small domesticated carnivorous mammal'
>
> In a real dictionary terms are bound to descriptions, but in the ruby
> dictionary
> of variables we would say terms are bound to objects, this boils down
> to exactly the same thing.
>
> Grok?


Seems pretty static and the emphasis is on the underlying objects
independant existence, which of course is very much
dependant on some live reference or it will be GC'd.

How would you explain?

a=a+1

Anyone who has written or studied the source code to an assembler knows
the
basics of symbols.

Symbol Table
Id Table/Array
1  "word1"
2  "word2"
3  "word3"

Thus in some simple pseudo assembler

loads R1,"word1"
loads R2,"word2"
loads R3,"word1"

assembles to

loads 1,1
loads 2,2
loads 3,1

All new symbols are added to the symbol table, and symbols are only ever
referenced by Id. I'd guess that most modern VM's would behave in a
similar
manner.






--
622fa8560c82dfaa59c91ec75efb0c19?d=identicon&s=25 Alex Combas (Guest)
on 2006-01-08 09:11
(Received via mailing list)
On 1/7/06, Lyndon Samson <lyndon.samson@gmail.com> wrote:

> How would you explain?
>
> a=a+1

I don't know if this is what you are looking for, but this is how I
would explain:

Remember the variable 'a' is only a term.
Terms are bound to objects, and we find out which term
to which object by looking them up in a dictionary.

When we make a request (such as: a = a+1) for ruby to do
some operations with a variable ruby will do a quick look-up
in its dictionary to see which object is currently bound to that
term and then attempt to do whatever operations we have requested
upon on the object to which the term is bound.

I think this is somewhat similar to your assembler example.
This topic is locked and can not be replied to.