Module Global Hash

#!/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

I've also tried putting both a @ and @@ infront of user_hash but irb
comes up with the same error.
--
Posted via http://www.ruby-forum.com/.

Remember that in Ruby, everything is an object and objects communicate
by passing messages (calling methods). So you can't get to variables
of an object (such as user_hash). You can only call methods that an
object responds to.

···

On Jan 28, 12:06 am, Ryan Lewis <c00lry...@gmail.com> 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

I've also tried putting both a @ and @@ infront of user_hash but irb
comes up with the same error.
--
Posted viahttp://www.ruby-forum.com/.

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

···

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

I think what's going on here is that when the parser gets to the line
that says

user_hash = {}

it looks for a method called user_hash to execute. It doesn't realize
that you're trying to instantiate a variable. Maybe you should
consider turning the Users module into a class and trying @@user_hash
= {} again.

···

On Jan 28, 12:17 am, Wyatt Greene <green...@yahoo.com> wrote:

On Jan 28, 12:06 am, Ryan Lewis <c00lry...@gmail.com> 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

> I've also tried putting both a @ and @@ infront of user_hash but irb
> comes up with the same error.
> --
> Posted viahttp://www.ruby-forum.com/.

Remember that in Ruby, everything is an object and objects communicate
by passing messages (calling methods). So you can't get to variables
of an object (such as user_hash). You can only call methods that an
object responds to.

Gary Wright wrote:

   class <<self

Hey, thanks man. I was thinking about defining and =, but I didnt
know about <<self.

···

--
Posted via http://www.ruby-forum.com/\.

> #!/usr/bin/env ruby
> module Users
> class User < Struct.new(:screenname, :password, :dob, :join_date,
> :age)

You do not need to inherit from the new struct class, instead you can do

User = Struct.new(:screenname, :password, :dob, :join_date, :age)
class User
...
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
> 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

Note though that this approach will prevent any User instance from
being garbage collected. This might or might not be what you want. I
do not know the use case but there is another option: you can traverse
all User instances via ObjectSpace.

Ah, and another remark: the implementations show so far will also
allow to create two users with the same name but only one of them will
be accessible via the Hash.

Kind regards

robert

···

2008/1/28, Gary Wright <gwtmp01@mac.com>:

On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:

--
use.inject do |as, often| as.you_can - without end

Wyatt Greene wrote:

···

On Jan 28, 12:17 am, Wyatt Greene <green...@yahoo.com> wrote:

> self.password = pw
> end

> I've also tried putting both a @ and @@ infront of user_hash but irb
> comes up with the same error.
> --
> Posted viahttp://www.ruby-forum.com/.

Remember that in Ruby, everything is an object and objects communicate
by passing messages (calling methods). So you can't get to variables
of an object (such as user_hash). You can only call methods that an
object responds to.

I think what's going on here is that when the parser gets to the line
that says

user_hash = {}

it looks for a method called user_hash to execute. It doesn't realize
that you're trying to instantiate a variable. Maybe you should
consider turning the Users module into a class and trying @@user_hash
= {} again.

I thought of this, but I'm going to be using a system with many many
users and each time I would call Users, I would crate two classes,
taking up twice as much memory.

Should I just drop the module and just keep it in a Users.rb file to
call it later?
--
Posted via http://www.ruby-forum.com/\.

I like:

User = Struct.new(…) do

end

James Edward Gray II

···

On Jan 28, 2008, at 4:18 AM, Robert Klemme wrote:

2008/1/28, Gary Wright <gwtmp01@mac.com>:

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)

You do not need to inherit from the new struct class, instead you can do

User = Struct.new(:screenname, :password, :dob, :join_date, :age)
class User
...
end

Of course. Unfortunately it does not work with class constants
properly. I should have mentioned that. (In my experiments I wanted
to use User::USERS.)

Thanks for pointing it out!

Kind regards

robert

···

2008/1/28, James Gray <james@grayproductions.net>:

On Jan 28, 2008, at 4:18 AM, Robert Klemme wrote:

> 2008/1/28, Gary Wright <gwtmp01@mac.com>:
>>
>> 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)
>
> You do not need to inherit from the new struct class, instead you
> can do
>
> User = Struct.new(:screenname, :password, :dob, :join_date, :age)
> class User
> ...
> end
>>

I like:

User = Struct.new(…) do

--
use.inject do |as, often| as.you_can - without end