# Is this how you start a hash?

**URL:** <https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302>\
**Category:** Ruby\
**Created:** [March 19, 2009, 1:52am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302 "2009-03-19T01:52:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 1:52am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/1 "2009-03-19T01:52:34Z")

</div>

I’m looking at the code below but still not clear about how this hash  
forms! The author of a ruby book I read claimed that the code forms  
hash. Is it?

#not complete code, if you try to use it, it won’t work!

require ‘yaml’  
require ‘wordplay’

class Bot  
attr\_reader :name

def initialize(options)  
@name = options[:name] || “Unnamed Bot”  
begin  
@data = YAML.load(File.read(options[:data\_file]))  
rescue  
raise “Can’t load bot data”  
end  
end  
end

So, when you created hash, don’t you have to initialize it with an empty  
hash? For example: @name = {}?

Also when I try to use a snippet in irb:  
@name = options[:name] || “Unnamed Bot”  
NameError: undefined local variable or method `options’ for main:Object  
from (irb):1  
from :0

options is also in File.read(), it’s acting like adding more element to  
a hash. Am I right? Though irb tells a different story as if it’s not  
how you starting a hash.

I’m confused!

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 2:14am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/2 "2009-03-19T02:14:36Z")

</div>

On Mar 18, 2009, at 7:50 PM, Power O. wrote:

> attr\_reader :name

Yes, you’d normally create a new has with either Hash.new or hash =  
{}. The method above is expecting that an already populated Hash be  
passed as its argument (internally referred to as the options  
variable). So here’s how you’d use the Bot class:

Bot.new(:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’)

Maybe this helps you see the Hash more clearly:

Bot.new({:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’})

or even:

my\_options = {:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’}  
Bot.new(my\_options)

Hope this helps.

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 3:07am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/3 "2009-03-19T03:07:37Z")

</div>

Power O. wrote:

> Also when I try to use a snippet in irb:  
> @name = options[:name] || “Unnamed Bot”  
> NameError: undefined local variable or method `options’ for main:Object  
> from (irb):1  
> from :0

h = {:name =\> “Joe”, :age =\> 20}  
name = h[:name]  
puts name

–output:–  
Joe

h = {:age =\> 30}  
name = h[:name] || “Unamed Bot”  
puts name

–output:–  
Unamed Bot

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 4:52am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/4 "2009-03-19T04:52:41Z")

</div>

This helps me a lot! 🙂

Plus from now on, if something looks like an array but without the index  
(ex: options[3]), then I can safely assumed it’s a form of hash but in a  
reading stage.

Thank guys!

lists wrote:

> On Mar 18, 2009, at 7:50 PM, Power O. wrote:
> 
> > attr\_reader :name
> 
> Yes, you’d normally create a new has with either Hash.new or hash =  
> {}. The method above is expecting that an already populated Hash be  
> passed as its argument (internally referred to as the options  
> variable). So here’s how you’d use the Bot class:
> 
> Bot.new(:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’)
> 
> Maybe this helps you see the Hash more clearly:
> 
> Bot.new({:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’})
> 
> or even:
> 
> my\_options = {:name =\> ‘My Bot’, :data\_file =\> ‘/tmp/file.yml’}  
> Bot.new(my\_options)
> 
> Hope this helps.

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 3:27am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/5 "2009-03-19T03:27:06Z")

</div>

On Thu, Mar 19, 2009 at 10:50 AM, Power O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> attr\_reader :name
> 
> def initialize(options)  
> @name = options[:name] || “Unnamed Bot”  
> begin  
> @data = YAML.load(File.read(options[:data\_file]))  
> rescue  
> raise “Can’t load bot data”  
> end  
> end  
> end

Not sure what the author was getting at but YAML#load will probably  
return a  
hash from the data file. The usage of options implies that a hash is  
passed  
as an argument

> So, when you created hash, don’t you have to initialize it with an empty  
> hash? For example: @name = {}?

@name looks like it’s supposed to be a string which is initialized from  
the  
options hash, the || notation means that if options[:name] doesn’t exist  
then it will default to “Unnamed Bot”.

> Also when I try to use a snippet in irb:  
> @name = options[:name] || “Unnamed Bot”  
> NameError: undefined local variable or method `options’ for main:Object  
> from (irb):1  
> from :0

You will need to initialize the hash in this case, or use variables, but  
it  
might be best if your using irb to use constants such as;  
@name = “Robocop”

> options is also in File.read(), it’s acting like adding more element to  
> a hash. Am I right? Though irb tells a different story as if it’s not  
> how you starting a hash.

No it’s not adding elements to the options hash, it is reading them.  
That  
line returns a hash to @data (which is probably the one you want) based  
on  
the contents of the file referred to by options[:data\_file].

> I’m confused!

Aren’t we all?

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 19, 2009, 6:35am UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/6 "2009-03-19T06:35:28Z")

</div>

On Mar 18, 2009, at 11:50 PM, Power O. wrote:

> This helps me a lot! 🙂
> 
> Plus from now on, if something looks like an array but without the  
> index  
> (ex: options[3]), then I can safely assumed it’s a form of hash but  
> in a  
> reading stage.
> 
> Thank guys!

No, you can assume that it is the [] method sent to the object  
referenced by options.

irb\> options = lambda {|x| x.to\_s.reverse }  
=\> #Proc:0x00007f8ce288b9b0@:1(irb)  
irb\> options[3]  
=\> “3”  
irb\> options[“hash”]  
=\> “hsah”  
irb\> options[:foo]  
=\> “oof”

For lambdas or Procs, this is the same as options.call(“hash”), etc.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![arghx1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/aca169/32.png) [@arghx1](https://www.ruby-forum.com/u/arghx1)\
**Post date:** [March 23, 2009, 5:02pm UTC](https://www.ruby-forum.com/t/is-this-how-you-start-a-hash/163302/7 "2009-03-23T17:02:00Z")

</div>

Power O. wrote:

> Plus from now on, if something looks like an array but without the index  
> (ex: options[3]), then I can safely assumed it’s a form of hash but in a  
> reading stage.

Any object can implement its own [] method with whatever semantics it  
likes, not just Arrays and Hashes. The [] method is used for lots of  
different purposes in the Ruby standard classes:

# Testing individual bits in an integer

irb(main):001:0\> 15[2]  
=\> 1

# Substrings

irb(main):002:0\> “abcdefg”[“cd”]  
=\> “cd”  
irb(main):003:0\> “abcdefg”[/d./]  
=\> “de”

# Filename globbing

irb(main):004:0\> Dir["/etc/\*"]  
=\> ["/etc/fstab", “/etc/X11”, “/etc/acpi”, “/etc/alternatives”,  
“/etc/apm” …]

# Procs

irb(main):005:0\> adder = lambda { |x,y| x+y }  
=\> #Proc:0xb7d968d8@:7(irb)  
irb(main):006:0\> adder[4,5]  
=\> 9

And you can define your own:

class Bot  
def   
…  
end  
def []=(x,y)  
…  
end  
end
