Is this how you start a hash?


#1

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!


#2

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.


#3

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


#4

This helps me a lot! :slight_smile:

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.


#5

On Thu, Mar 19, 2009 at 10:50 AM, Power O. 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?


#6

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

This helps me a lot! :slight_smile:

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
removed_email_address@domain.invalid


#7

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