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