Gary Wright
1/28/2008 5:57:00 AM
On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:
> #!/usr/bin/env ruby
> module Users
> class User < Struct.new(:screenname, :password, :dob, :join_date,
> :age)
> def initialize(sn, pw, dob)
> self.screenname = sn
> self.password = pw
> self.dob = Time.parse(dob)
> self.join_date = Time.now
> self.age = Time.now.year - Time.parse(dob).year
> end
> end
> #########################################
> user_hash = {}
>
> def new(sn, pw, dob)
> Users::user_hash[sn] = User.new(sn, pw, dob)
> end
> #########################################
> module_function :new
> end
>
> I'm trying to make it so when I call:
> Users::new("screenname", "pass", "1/15/91")
>
> it adds a new instance of the User class into user_hash, but when I
> execute the above code in IRB I get a NoMethodError for user_hash for
> the Users:module
The way you've used it, user_hash is a local variable for the module
Users block. It disappears when the block ends.
You don't need a separate enclosing module. You've already got User.
In the following code, I used an instance variable of User,
@user_hash, to store the instances by name, User#initialize adds the
entry, and for added ease of use, I defined User.[] and User.[]= as a
way to access @user_hash.
require 'time'
class User < Struct.new(:screenname, :password, :dob, :join_date, :age)
class <<self
def [](u)
user_hash[u]
end
def []=(name, struct)
user_hash[name] = struct
end
def user_hash
@user_hash ||= {}
end
end
def initialize(sn, pw, dob)
self.screenname = sn
self.password = pw
self.dob = Time.parse(dob)
self.join_date = Time.now
self.age = Time.now.year - Time.parse(dob).year
self.class[sn] = self
end
end
User.new('bob', 'pw', '1/1/01')
p User['bob']
p User.user_hash