fetch method of session hash

Is there something special about the session hash that would make it
so that I can not access its associated fetch method? In attempting
to do so I keep getting complaints that there is no such method.
Thanks for any input.

             ... doug

It responds to fetch just fine for me. Can you send the code and error?

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

It's not a hash;

Well, that probably goes a long way towards explaining the absence of
the fetch method. :slight_smile: Thanks a lot for the detailed explanation.

     ... doug

Julian Leviston wrote:

It responds to fetch just fine for me. Can you send the code and error?

Hey, me too!

class StoreController < ApplicationController

  def index
    session[:test] = 10

    puts "***************"
    print "[]: ", session[:test]
    puts
    print "fetch: ", session.fetch(:test, "Couldn't find.")
    puts
    print "fetch: ", session.fetch(:bird, "Couldn't find bird.")
    puts
    puts "****************"
  end

end

--output in server window:--

Can you send the code and error?

Sure. Here's the offending line:

session[:target_uri]='/admin' if !session.fetch(:target_uri,nil)

And here's the full controller code (See specifically line 10)

      1 class LoginController < ApplicationController
      2
      3 def login()
      4 # begin
      5 if defined? params && params.has_key?('login')
      6 record=Admin.find(:first,:conditions=>["Login=?",params
['login']])
      7 if record && record.Password==params.fetch
('password','')
      8 session[:user_id]=record.id
      9 session[:login]=record.Login
     10 session[:target_uri]='/admin' if !session.fetch
(:target_uri,nil)
     11 uri=session[:target_uri]
     12 session[:target_uri]=nil
     13 redirect_to(uri) && return
     14 else
     15 session=nil
     16 redirect_to(:action=>'index') && return
     17 end
     18 end
     19 # rescue
     20 # redirect_error($!)
     21 # end
     22 end

And finally, here's the error message:

NoMethodError in LoginController#login
undefined method `fetch' for #<CGI::Session:0xb6c036ac>

Thanks.

       ... doug

And finally, here's the error message:

NoMethodError in LoginController#login
undefined method `fetch' for #<CGI::Session:0xb6c036ac>

You're running a different rails version (2.2.2 or less), whereas the
others must be using 2.3.2 (session handling got a revamp).

Fred

You're running a different rails version (2.2.2 or less), whereas the
others must be using 2.3.2 (session handling got a revamp).

Two things:

1. Under the revamp is 'session' a real hash?

2. From my code you probably saw what I was trying to do.
Specifically, I was attempting to use the fetch method to test whether
a specific key was in the session hash and return nil if it wasn't.
I'm wondering what the best way to do this is knowing what's coming
down the pike. Maybe (and it scares me to even think about this) I
could somehow add a fetch method to the quasi session hash. Then my
code would be compatible with what's coming in the later version. I'm
pretty darn sure that I'm not smart enough to do that; but, it's
something to think about. Any suggestions on how I should handle
this? Thanks.

         ... doug

> You're running a different rails version (2.2.2 or less), whereas the
> others must be using 2.3.2 (session handling got a revamp).

Two things:

1. Under the revamp is 'session' a real hash?

it's a special hash (because there's crafty stuff to do with lazy
loading)

2. From my code you probably saw what I was trying to do.
Specifically, I was attempting to use the fetch method to test whether
a specific key was in the session hash and return nil if it wasn't.
I'm wondering what the best way to do this is knowing what's coming
down the pike. Maybe (and it scares me to even think about this) I
could somehow add a fetch method to the quasi session hash. Then my
code would be compatible with what's coming in the later version. I'm
pretty darn sure that I'm not smart enough to do that; but, it's
something to think about. Any suggestions on how I should handle
this? Thanks.

Is
if session[:foo]
...

not good enough for you (or do you sometimes explicitly store nil in
the session (and want that to be distinct from the value not being
there at all) ?) ?

Fred

Is
if session[:foo]
...

not good enough for you (or do you sometimes explicitly store nil in
the session (and want that to be distinct from the value not being
there at all) ?) ?

Actually the distinction between nil and nothing is exactly the issue;
but, it's not what you're thinking. It has to do with the definition
of truth.

My understanding is that in Ruby what is not true is limited to either
nil or the constant, false. My recollection is that, in the past on
some occasions, I have gotten myself into trouble by treating the
absence of a value as being equivalent to false. So, I keep reminding
myself that, in Ruby, the absence of a value is not equivalent to
false and I try to write code accordingly.

Now, I want to clarify the above statement. My recollection of the
cases in which I have previously gotten into trouble didn't involve a
hash; but, rather, I was doing something like, "if foo" and the
trouble arose when the foo variable had not been defined. So, I
realize that is not the same thing as a key being absent from a hash.
Perhaps I can get away with it in the case of a hash. If so, I'm just
going to have to expand my understanding of what constitutes false in
Ruby to include the absence of a key from a hash. So, out of
curiosity, is it your understanding that, in Ruby, false includes the
absence of a key from a hash?

Thanks.

     ... doug

Now, I want to clarify the above statement. My recollection of the
cases in which I have previously gotten into trouble didn't involve a
hash; but, rather, I was doing something like, "if foo" and the
trouble arose when the foo variable had not been defined. So, I
realize that is not the same thing as a key being absent from a hash.
Perhaps I can get away with it in the case of a hash. If so, I'm just
going to have to expand my understanding of what constitutes false in
Ruby to include the absence of a key from a hash. So, out of
curiosity, is it your understanding that, in Ruby, false includes the
absence of a key from a hash?

it's not so much what constitutes false as what [:foo] returns if the
hash doesn't have a value for that key (and by default that's nil)

Fred

Doug Jolley wrote:

If so, I'm just
going to have to expand my understanding of what constitutes false in
Ruby to include the absence of a key from a hash.

Your understanding of what 'evaluates' to false in a boolean setting,
like an if statement, is spot on. false obviously evaluates to false,
but the only other thing that evaluates to false is nil.

The thing you need to expand your understanding of is: the possible
return values of the methods you call. A hash returns nil if the key
doesn't exist (or a default value if a default value was set when the
hash was created).

So, yeah you can rely on a hash returning nil if the key doesn't exist,
and also that nil will evaluate to false.

So, out of
curiosity, is it your understanding that, in Ruby, false includes the
absence of a key from a hash?

I don't think of it in such abstract terms. If I the key doesn't exist,
the '[]' method returns nil.

Actually the distinction between nil and nothing

Actually, it's the distinction between nil and false and anything else.
If the object you are evaluating in an if statement is not specifically
nil or false, then it will evaluate to true, period. A concept like
"absence of nothing" is totally irrelevant and not worth thinking about.
Experienced programmers in other languages often get tripped up by ruby
because they expect things like empty strings(""), empty arrays([]) or
empty hashes({}) to evaluate to false. But because none of those things
is specifically false or nil, they evaluate to true. It's that simple.

As a result, the way you used fetch in your code doesn't do anything
different than the '[]' method would do.

I've got it! :slight_smile: *AND*, I don't have to expand my thinking about
what's true and what's false in Ruby. What I have to keep in mind is
that hashes return a default value for an undefined key. Unless some
other value for the default was set at the time the hash was created,
the default value is nil. So, when no default value is explicitly set
at the time the hash is created, there is no real difference between:

if myHash[:akey]

and

if myHash.fetch(:akey,nil)

As I say, I think that I have it! :slight_smile:

Thanks to all who contributed.

        ... doug