On Dec 9, 2009, at 8:44 PM, johncch wrote:
> Hi,
>
> I'm trying to understand the implementation of MetaMegaProtoUser,
> reading the code, there are a couple of conceptual questions that I'd
> like to ask.
>
> I understand object as a singleton class, or perhaps vaguely similar
> to a static class (as in Java) so I'm wondering why is, in the
> MetaMegaProtoUser trait, the curUserId an object.
>
> In the sense, perhaps I can imagine an object inside an object is
> simple a singleton within a singleton, but the confusion kinda arises
> when it extends SessionVar. From my understanding of the functionality
> of SessionVars, it actually keeps the user logged in across sessions.
> So, I'm trying to understand how does a singleton in a singleton keeps
> the log in information safe? If I have multiple users on the site at
> the same time, why is the value not overwritten?
SessionVars are kind of like thread local variables. They have an internal "name" (which is guaranteed to be unique and is maintained by Lift) which is used to check in a dictionary the session keeps around with the values of each SessionVar for the current session.
When you access a SessionVar with myVar.is (or myVar.get, or using the implicit) under the covers it obtains the current session from a thread local variable in S (I believe, maybe it's in LiftSession) and then looks for the value for the variable in the current session. If not found, it executes the initializer to pick an initial value.
Similarly, when you set a SessionVar with myVar.set the same kind of thing happens except it stores the value you give it in the session.
So, the singleton within a singleton is essentially only keeping that unique name you don't need to know about.
> I suspect this is related to the deficiency in my knowledge in how
> sessions are actually implemented, but please bear with me..
>
> So, I look at the loggedIn_? method that is constantly called on the
> User object, it actually looks at currentUserId.isDefined, so I assume
> that the currentUserId, once set via the login method will persist
> throughout the session. How is that achieved? Is there a method at the
> beginning of lift's lifecycle that sets this variable via looking at
> the session information?
curUserId is set via the mechanism I describe earlier in MetaMetaProtoUser's login handling.
> Lastly, I'd like to ask where is the remove() method defined on the
> curUserId private object? I've looked at the implementation of
> SessionVar and AnyVar and I couldn't seem to find it.
It's on AnyVar. Finding where a method is implemented is made alot easier by using the vscaladocs and checking the "Inherited" box at the bottom right of each page. Here's a direct link to the lift-webkit docs (1.1-SNAPSHOT):
http://www.scala-tools.org/mvnsites-snapshots/liftweb/lift-webkit/scaladocs/index.html
By the way, if you're not using 1.1-SNAPSHOT (soon to be 2.0-SNAPSHOT), you definitely should. It's leagues ahead of 1.0 and tends to be stable.
> I'm hacking on a small-ish project and it's been a fun and frustrating
> journey so far. Love the framework, it makes doing things very
> flexible and easy, but the flexibility of the language is kinda
> daunting.. sometimes it really makes my brain hurt. But will try
> harder!
Good! If you get stuck always feel free to ask questions on the mailing list. We like helping.
-Ross