Lua global variable in module staying nil? - variables

Im starting to learn Lua modules a bit, and I am having troubles with a small part in my Lua.
Everytime I change my variable it reverts back to nil.
myModule.lua
--I should note that client is a number.
module(..., package.seeall)
local LoggedIn = { }
function isLogged( client )
return LoggedIn[client]
end
function logIn(client)
table.insert(LoggedIn,client,true)
end
function logOut(client)
table.remove(LoggedIn,client)
end
main.lua an event happens
package.loaded.myModule= nil; require "myModule"
function event( client )
myModule.logIn(client)
end
function event_2( client )
myModule.logOut(client)
end
EDIT: Using functions instead, and making it local variable.
It is still returning nil even though I can confirm the logIn function happened with no errors. Without even using the logout function yet.
Any thoughts?
but later on in main.lua I check if client is logged in and it just returns nil.
Is this just a limitation of modules or am I just accessing the variable wrong.
I should note I need to be able to do this in other Luas that acces myModule.lua too.
Thanks in advance

You don't really give us enough code to fully help you, but this is a working example I set up based on what little example you gave us:
-- myModule.lua
module(..., package.seeall)
LoggedIn = {}
function isLoggedIn(client)
return LoggedIn[client] ~= nil
end
function LogIn(client)
LoggedIn[client] = true
end
function LogOut(client)
LoggedIn[client] = nil
end
and to test it:
-- main.lua
require "myModule"
myModule.LogIn("Joe")
myModule.LogIn("Frank")
print(myModule.isLoggedIn("Bill"))
print(myModule.isLoggedIn("Frank"))
myModule.LogOut("Joe")
print(myModule.isLoggedIn("Joe"))
this prints out as expected:
false
true
false
so my guess is that you are not checking the conditions correctly for LoggedIn[client] being empty, or you never actually remove entries from the LoggedIn table when someone 'logs out'.

The following using your own code (assuming you fix typo in funtion) works (it prints true\nnil):
package.loaded.myModule= nil; require "myModule"
function event( client )
myModule.LoggedIn[client] = true
end
event("foo")
print(myModule.isLogged("foo"))
A better way to do this would be to add a function logIn as #Mike suggested and avoid using module(); you can use something like this instead:
local myModule = require "myModule"
function event( client )
myModule.logIn(client)
end
event("foo")
print(myModule.isLogged("foo"))
print(myModule.isLogged("bar"))
And myModule.lua becomes:
local LoggedIn = { }
function isLogged( client )
return LoggedIn[client]
end
function logIn( client )
LoggedIn[client] = true
end
return { LoggedIn = LoggedIn, isLogged = isLogged, logIn = logIn }

Related

Rspec: Stubbing out a where statement in a controller test

I'm writing the following test:
let!(:city_areas) { FactoryGirl.create_list(:city_area, 30) }
before {
#city_areas = mock_model(CityArea)
CityArea.should_receive(:where).and_return(city_areas)
}
it 'should assign the proper value to city areas variable' do
get :get_edit_and_update_vars
assigns(:city_areas).should eq(city_areas.order("name ASC"))
end
to test the following method:
def get_edit_and_update_vars
#city_areas = CityArea.where("city_id = '#{#bar.city_id}'").order("name ASC").all
end
However, it fails out, saying that there's no method 'city_id' for nil:NilClass, leading me to believe it's still attempting to use the instance variable #bar.
How do I properly stub out this where statement to prevent this?
Why are you doing #city_areas = mock_model(CityArea) and then you never use #city_areas again?
I would test it this way:
inside the model CityArea create a named scope for this: where("city_id = '#{#bar.city_id}'").order("name ASC")
then in your controller spec you do
describe 'GET get_edit_and_update_vars' do
before(:each) do
#areas = mock('areas')
end
it 'gets the areas' do
CityArea.should_receive(:your_scope).once.and_return(#areas)
get :get_edit_and_update_vars
end
it 'assign the proper value to city areas variable' do
CityArea.stub!(:your_scope => #areas)
get :get_edit_and_update_vars
assigns(:city_areas).should eq(ordered)
end
end
and you should also create a spec for that new scope on the model spec
just a tip, you shouldn't use should_receive(...) inside the before block, use stub! inside before and use should_receive when you want to test that method is called
also, you shouldn't need to use factorygirl when testing controllers, you should always mock the models, the model can be tested on the model spec

OOP in Corona, accessing vars from outside class

looking for some help with accessing variables from outside a Corona OOP class. Here's the bare-bones code:
module(..., package.seeall)
local widget = require "widget"
picker = {}
picker.__index = picker
function picker.new()
local picker_object = {}
setmetatable(picker_object,picker)
picker_object.theHour = 12
picker_object.theMin = 0
picker_object.am = true
return picker_object
end
function picker:getHour()
return self.theHour
end
function picker:getMin()
return self.theMin
end
self is coming back as nil when I try and call getHour and getMin from outside the class. What syntax should I use instead to return my theHour and theMin variables?
Thanks!!
I tried out your code and there's nothing wrong with it. The problem is probably in the way you're accessing this module. Here's my main.lua that works with your code (I gonna guess your file is named picker.lua):
local picker = require "picker"
local picker_obj = picker.picker.new()
-- the first picker is the module (picker.lua)
-- the second is the picker class in the file
print("minute: " .. picker_obj:getMin())
print("hour: " .. picker_obj:getHour())
Also, The module(..., package.seeall) command has been deprecated, see this blog post for a better way to make your module. If you use this method to create your module and still call your file picker.lua, the first two lines in my main.lua would change to:
local picker = require "picker"
local picker_obj = picker.new()
Here's the simplest way I would modify your code to use the new way of creating modules. Only the beginning and end change, everything else stays the same:
-- got rid of module(), made picker local
local picker = {}
picker.__index = picker
... -- all the functions stay the same
return picker

Context issue in IHttpHandler

Sorry, this can be a basic question for advanced VB.NET programmers but I am a beginner in VB.NET so I need your advice.
I have a web application and the login is required for some specific pages. To check if the user is logged in, the old programmer used this technique:
Dim sv As New WL.SessionVariables(Me.Context)
If Not (sv.IsLoggedIn) Then
Response.Redirect(WL.SiteMap.GetLoginURL())
End If
Well, I have to use this Logged In checking in a handler done by me and I tried this:
Public Class CustomHandler
Implements System.Web.IHttpHandler, IReadOnlySessionState
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sv As New WL.SessionVariables(context)
If Not (sv.IsLoggedIn) Then
context.Response.Write("No access unless you're the CEO!!!" & sv.IsLoggedIn)
ElseIf sv.IsLoggedIn Then
DownloadFile(context)
Else
End If
End Sub
//other code
End Class
Well, the "is logged in" checking is always false (even after I login) and I think it's an issue with the context. So all the other pages works fine with logging checking but this handler have this specific issue.
Can you guys give a helping hand?
UPDATE:
The logged in is done trough this method:
Public Sub SetCreditialCookie(ByVal accountID As Integer)
Me.AccountID = accountID
m_context.Session.Item("loggedInAccount") = accountID
m_context.Response.Cookies.Add(New System.Web.HttpCookie("account_id", CStr(m_context.Session.Item("account_id"))))
m_context.Response.Cookies("account_id").Expires = DateTime.Now.AddDays(5)
End Sub
and to check it it's logged in, this method is called:
Public Function IsLoggedIn() As Boolean
If Not m_context.Session.Item("loggedInAccount") Is Nothing And Me.AccountID = m_context.Session.Item("loggedInAccount") Then
Return True
Else
Return False
End If
End Function
UPDATE 2:
- debugging the code shown that there were multiple kind of logins and I was checking the wrong one with the session.
Due to the use of IReadOnlySessionState, is it possible that the SessionVariables class attempts in some way to modify the Session, which in turn causes an error (possibly handled and not visible to you).
If this is the case it could mean that the IsLoggedIn property is not correctly initialised, or does not function as expected?
Do you have access to the code for the class. If so, try debugging it to see what is happening.

Want to return a global variable instead of a local variable

I am verifying the existence of "test_results" in the application controller. It is returned as a local variable. I would like to call it once and have it available for the whole session. How do i do that?
"test_results" in application controller:
def test_results
(0 .. 4).each do |x| # looks for answers to the first 4 questions
if #answers[x].nil? || #answers[x] == 0.0
return false
break
end
end
return true
end
other controllers:
before_filter :test_results
if test_results
...do stuff
else
...display "take the test"
end
error message from view:
undefined local variable or method `test_results'
You can try using #
if #instrument_results
Edit
The result of before filter isn't stored. I don't know what you want to do but you can set a controller level variable inside the test_results function and then referer it as #controller.variable_name. But if your intention is to make a conditional view based on test_results return value, I suggest you to make a redirect to another action in the test_results method and put the success content in the current controller.
You can use :only and :except modifier to check which action of the controller will call the :before_filter.
Hope this helps.

Returning external data from a function in ActionScript

I have the following script that is calling a text file:
/* first create a new instance of the LoadVars object */
myVariables = new LoadVars();
myVariables.load("myFile.txt");
myVariables.onLoad = function(getreading):String{
var ODOMETER2:String=myVariables.ACADEMICWATER;
return ODOMETER2;
trace (ODOMETER2);
}
trace(getreading());
The text file contains the following:
ACADEMICWATER=3002&elec=89
I am able to import the value of 3002 into the function and I can trace it. However, I Should be able to trace it outside the function using trace(getreading()); as shown on the last line. This only returns an "UNDEFINED" value. I am stumped.
You are declaring an anonymous function (see AS3 Syntax and language / Functions) which can't be referenced by name. getreading is declared in your code as an untyped parameter of this function.
If you want to trace the result of this function, then you should declare a named function like this:
function getReading(): String {
var ODOMETER2:String=myVariables.ACADEMICWATER;
return ODOMETER2;
}
myVariables.onLoad = getReading;
trace(getReading());
getreading is not the name of the function in this case, but the name of a parameter to the anonymous function that is run on the onLoad event of the myVariables object.
Place the variable ODOMETER2 outside the function and set it's value inside the anonymous function. Then you will be able to access it outside the function as well.
/* first create a new instance of the LoadVars object */
var ODOMETER2:String;
myVariables = new LoadVars();
myVariables.load("myFile.txt");
myVariables.onLoad = function(){
ODOMETER2=myVariables.ACADEMICWATER;
}
trace(ODOMETER2);
LoadVars.onLoad is an event handler. It is called by LoadVars as soon as it finishes with the asynchronous load operation. It takes a boolean argument, indicating success or failure of the operation. It does not return anything.
LoadVars.onLoad documentation
In that function, you typically act upon the data you received, like storing and processing it. Here's a very simple example showing some basic use cases:
var ODOMETER2:String;
var myVariables = new LoadVars();
myVariables.load("myFile.txt");
myVariables.onLoad = function(success) {
trace(success);
ODOMETER2 = myVariables.ACADEMICWATER;
processResults();
}
function processResults() {
trace(ODOMETER2);
trace(myVariables.ACADEMICWATER);
}
// traces:
// true
// 3002
// 3002