test to see if a variable exists

Discussion in 'Ruby' started by Colin Summers, Jun 15, 2007.

  1. So I am stealing all these identities and storing everything in a big
    array of objects stolen_identity, and having the index be social
    security numbers:

    ss[34323843] = Stolen_identity.new

    But say I pick up a paycheck stub and it has 3428294. How do I know if
    I already have it? Does
    if (exist ss[3428294]) then ... end
    work? How can I see if a variable exists?

    Thanks.

    (please include your social security with your answer)
     
    Colin Summers, Jun 15, 2007
    #1
    1. Advertisements

  2. Colin Summers

    Phrogz Guest

    Arrays (and Hashes) in Ruby are sparse - they only store the values
    you actually enter. However, there are some limitations on the size of
    indices for arrays:

    C:\>irb

    irb(main):001:0> ss = []
    => []

    irb(main):002:0> ss[ 884_56_2103 ] = "I HAVE YOU NOW"
    ArgumentError: index too big
    from (irb):2:in `[]='
    from (irb):2

    So, you probably want to use a Hash, which has no such limitation.
    With both Arrays and Hashes, supplying a key or index which has no
    stored value will return a nil object:

    irb(main):003:0> ss = {}
    => {}

    irb(main):004:0> ss[ 884_56_2103 ] = "I HAVE YOU NOW"
    => "I HAVE YOU NOW"

    irb(main):005:0> ss[ 912_34_3552 ]
    => nil

    In Ruby, nil and false are both non-truth values for the purposes of
    boolean logic. Additionally (and slightly more cleanly), you can ask a
    Hash directly if it has an entry for a specific key:

    irb(main):006:0> if ss.has_key?( 884_56_2103 ) then
    irb(main):007:1* puts "I'm done with this guy"
    irb(main):008:1> else
    irb(main):009:1* puts "Sweet new information!"
    irb(main):010:1> end
    I'm done with this guy
     
    Phrogz, Jun 15, 2007
    #2
    1. Advertisements

  3. Using a hash is the way to go here. You've already been advised to do
    that. But here is an example that may give you some additional insight.

    <code>
    class Identity
    def initialize(ss)
    @ss = ss
    end
    def process
    puts "#{@ss}: I've been stolen!"
    end
    end

    Stolen = {}

    ss1 = '123-12-1234'
    ss2 = '789-78-7890'
    Stolen[ss1] = Identity.new(ss1)

    # One way
    Stolen[ss1].process if Stolen[ss1] # process runs
    Stolen[ss2].process if Stolen[ss2] # process does not run

    # Another way
    Stolen[ss1].process rescue nil # process runs
    Stolen[ss2].process rescue nil # process does not run
    </code>

    There are many other ways, but they all rely on same thing: that
    Stolen[ss2] returns nil and nil is treated as false in boolean
    expressions.

    Regards, Morton
     
    Morton Goldberg, Jun 15, 2007
    #3
  4. Colin Summers

    John Joyce Guest

    An array could indeed work. Think about the structure of a SSN:
    377-23-4736 (not a real one)
    That looks like a multi-dimensional array to me.
    each part is limited: 3 digits, 2 digits, 4 digits.
    Much like IPv4 this can produce a lot of distinct numbers.
    These smaller parts are easier to process, possibly less overhead.
     
    John Joyce, Jun 16, 2007
    #4
  5. I don't doubt that Identity objects could be indexed into some kind
    of array, but I do think the hash approach is simpler and easier to
    implement. I'd be happy to be convinced otherwise. How about posting
    some code to prove your point?

    Regards, Morton
     
    Morton Goldberg, Jun 16, 2007
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.