I need to call a function of an object and pass it a variable. Because I need to make multiple call to function of this object I've tried to make one only handler that invoke the specific function by the form value I pass it. The code works, but CFBuilder show me that there is an error (missing semicolon on the last row). I'm on Railo.
local.myReport = seoUtility.init();
local.func = form.action;
local.report = local.myReport[local.func](form.user);
So the question is: this code is correct? I could simply ignore the cfbuilder error icon?
If you don't want CFBuilder to nag you about the syntax, you can change to this:
local.myReport = seoUtility.init();
local.func = local.myReport[form.action];
local.myReport.func = local.func;
local.report = local.myReport.func(form.user);
This sets local.func to the instance of seoUtility as a reference to the actual function you want to call, preserving its relationship to the parent object. This way the offending []() syntax isn't needed.
However, this only works if seoUtility.init() is returning a fresh instance every time, as opposed to a singleton shared by the application, in which case there would be a race condition on all calls to local.myReport.func().
Related
What I was doing before was that I was calling a function of my interface and it determinate in a switch condition thanks to a parameter what to do with the data. What kind of specialization they have.
But now, what I am trying to create a local object, treat it, and then add it to my containers of the interface.
In order to do that I have to copy all the value of my local object (which have been treated) in my container of the interface.
So I created a copy_cell function in the interface, a virtual one, and one in the subclass. But whenever I try to do it the interface function is called and not the subfunction.
GridCell_voxel * local_cell;
local_cell = new GridCell_voxel(m_grid_map( cell2matindex_x(cell_index_x), cell2matindex_y(cell_index_y))->getVoxelResolution(), m_grid_map( cell2matindex_x(cell_index_x), cell2matindex_y(cell_index_y))->getVoxel().size());
local_cell->process_points(relevant_points, m_mapping_type);
//This is the line I need to change
local_cell->copy_cell (m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y))) ;
Do you have any idea on the way to go? What am I missing here?
Sorry for the lack of information, i will try to expose how i managed and what i was actually looking for.
So i have a container of IntefaceCell, called m_grid_map, full of cell that has been specialized. In my case m_grid_map is full of GridCell_voxel which is a sub class from InterfaceCell.
What i want to do is, create a new local GridCell_voxel, copy the information in it. Then process the informations, then copy the local cell in the container.
The important part is the dynamic_cast in the copy cell function, which allow you to take an InterfaceCell as argument and then treat it as GridCell_voxel.
//Main.cpp
GridCell_voxel * local_cell;
local_cell = new GridCell_voxel();
local_cell->copy_cell (m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y)));
local_cell->process_points(relevant_points, m_mapping_type);
m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y))->copy_cell (local_cell);
delete local_cell;
//GridCell_voxel.cpp
void GridCell_voxel::copy_cell(GridCellInterface* cell) {
GridCell_voxel* voxel_cell = dynamic_cast<GridCell_voxel*>(cell);
this->m_voxel_start_height = voxel_cell->m_voxel_start_height;
this->init = true;
this->m_ground_voxel_position = voxel_cell->m_ground_voxel_position;
}
I hope it will help someone.
So, I'm writing some python scripts and I have some code like the one shown below:
a = 3
dict = {"run":runMiles(a)}
a = 5
The runMiles func takes one variable that is an int. For some reason when dict["run"] is called, the variable doesn't seem to use the "new" variable. It is important to realize that both a and dict are global variables
It does so because the function runMiles() executes at the time this line dict = {"run":runMiles(a)} executes and when you call dict["run"] it will only give the return value got after execution of the function and does not execute the function again to fetch the value of "run" and thus the value does not get updated.
I have an error that seems to be associated with <cfscript> db operation
// traffic tracking
myQry = new Query();
myQry.setSQL("INSERT INTO dbo.Traffic (Circuit, Fuseaction, IP_hash) VALUES (:circuit, :fuseaction, :ip_hash)");
myQry.addParam(name="circuit", value="#listfirst(rc.fuseaction, '.')#", cfsqltype="CF_SQL_VARCHAR");
myQry.addParam(name="fuseaction", value="#listlast(rc.fuseaction, '.')#", cfsqltype="CF_SQL_VARCHAR");
myQry.addParam(name="ip_hash", value="#cgi.remote_addr#", cfsqltype="CF_SQL_VARCHAR");
myQry.execute();
The really strange thing is, it looks like the operation completed. What kind of a error is this?
Short answer: It's probably a scoping issue. Try:
var myQry = new Query();
Long-winded waffley answer:
I'd call it an Adobe-developers-being-useless kind of error.
If you look at line 460 of that file, you'll see the error is due to a failure of StructFind to find the query name in the variables scope, and the reason it's appearing in debug input is because there's a try/catch with type any surrounding it. The same functionality could be achieved without causing/catching an error by replacing the try/catch with <cfif StructKeyExists(variables,tagAttributes['name']) > which is basic CFML knowledge, and certainly something a developer of the CF product should know!
The same code still exists in the CF10 version of base.cfc, so you may or not feel like submitting it as a bug in Adobe's CF bugbase - though it's unlikely they'll fix it for CF9 (and uncertain whether they'll feel CF10 is worth the effort either).
However, that would only be side-stepping the issue of the variable not existing, not addressing the real issue of why it doesn't actually exist. Given that the debug info shows the query is successfully executing, and the query code is basically right above that line (starts at line 442), it shouldn't be a repeated/common error, but it may be due to your myQry variable not being scoped, and thus it could be colliding with another variable also called myQry (or even the same var from a separate call to the function) which is happening between the execution of the new Query() and .execute() lines, and thus causing the original query to not be there when the StructFind looks for it.
The solution is to put the keyword var before the first use of myQry which will place it in the local scope for that function - something that should be done for all variables that are only for use within an instance of a function, (otherwise they are placed in the variables scope of the component/request that the function exists within).
Is it possible to get an existing object reference using CEF API?
For example I run a script using ExecuteJavaScript()
function foo()
{
var self = this;
self.value="some value";
}
var fooObj = new foo;
This script creates a new variable fooObj. It is possible to get a reference to this variable later in the C++ code and to modify its value?
You should be able to get it by doing something like the following (untested):
auto context = AppGetBrowser()->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> p = context->GetGlobal()->GetValue(CefString("fooObj"));
You may need to Enter/Exit the context depending on where you're calling it from in C++. Furthermore you may need to actually reference your object explicitly as 'window.fooObj' in which case you'll have to get the value for 'window' and then get 'fooObj' off that.
(edit - accidentally posted too early)
(edit 2 - more)
My current problem is that I have several enemies share the same A.I. script, and one other object that does something different. The function in the script is called AILogic. I want these enemies to move independently, but this is proving to be an issue. Here is what I've tried.
1) Calling dofile in the enemy's constructor, and then calling its script function in its Update function which happens in every game loop. The problem with this is that Lua just uses the script of the last enemy constructed, so all of the enemies are running the same script in the Update function. Thus, the object I described above that doesn't use the same script for it's A.I. is using the other enemies' script.
2) Calling dofile in the Update function, and then calling its script function immediately after. The problem with this is that dofile is called in every object's update function, so after the AILogic function runs and data for that script is updated, the whole thing just gets reset when dofile is called again for another enemy. My biggest question here is whether there is some way to retain the values in the script, even when I switch to running a different one.
I've read about function environments in Lua, but I'm not quite sure how to implement them correctly. Is this the right direction? Any advice is appreciated, thanks.
Edit: I've also considered creating a separate place to store that data rather than doing it in the Lua script.
Edit2: Added some sample code. (Just a test to get the functionality working).
-- Slime's Script
local count = 0;
function AILogic( Slime )
--Make the slime move in circles(err a square)
if count < 4 then
Slime:MoveDir( 0 );
elseif count < 8 then
Slime:MoveDir( 2 );
elseif count < 12 then
Slime:MoveDir( 1 );
elseif count < 16 then
Slime:MoveDir( 3 );
else
count = 0;
end
count = count + 1;
end
The lua interpreter runs each line as its own chunk which means that locals have line scope, so the example code can't be run as-is. It either needs to be run all at once (no line breaks), without locals, or run in a do ... end block.
As to the question in the OP. If you want to share the exact same function (that is the same function at runtime) then the function needs to take the data as arguments. If, however, you are ok with using the same code but different (runtime) functions than you can use closures to hold the local/individual data.
local function make_counter()
local count = 0
return function ()
local c = count
count = count + 1
return c
end
end
c1 = make_counter()
c2 = make_counter()
c3 = make_counter()
print(c1())
print(c1())
print(c1())
print(c1())
print(c2())
print(c3())
print(c2())
print(c3())
print(c2())
print(c3())
Alternatively, you could play with the environment of the function each time it is called, but that will only work correctly for some cases (depends on what the internals of the function are).
The canonical reference for this is link text. Explaining this briefly we'll work off the following code from the site:
a = 1
local newgt = {} -- create new environment
setmetatable(newgt, {__index = _G})
setfenv(1, newgt) -- set it
The first line sets up the (global) variable "a". You can view this as setting default values for your code. (Keep in mind that in Lua all variables are global unless you declare them with "local".)
The next line creates a table that will be your new environment. It is local to the function/chunk you're executing in so it won't be trashed by anything else that runs now or later.
The third line is the beginnings of the magic. To understand it you're going to have to understand metamethods In essence, however, you're using Lua's metamagic to ensure that any global names that aren't defined in your soon-to-be function environment get resolved in the context of your old global environment. Basically it means if you use a name that's not in your function environment, Lua will automagically hunt in the global environment you used to have to find the name. (In a word: inheritance.)
The fourth line is where you get what you're looking for. Setfenv(1,...) means that this changes the environment for your current function. (You could use 2 for the calling function, 3 for the calling function's caller, etc. on up the line.) The second parameter is the table you just set up, complete with inheritance of the old behaviour. Your function is now executing in a new global environment. It has all the names and values of the old environment handy (including functions and that global variable "a" you put in). If, however, you WRITE to a name it will not overwrite the global state. It will overwrite your local copy of it.
Consider the following subsequent code:
a = 10
b = 20
What you have done now is made your function environment table look like this:
{a = 10, b=20}
Your "global" environment, in short, contains two variables only: a (value 10) and b (value 20). When you access "a" later you'll get your local copy with 10 -- the old global value stored in your metatable is shadowed now and is still set to 1 -- and if you access "b" you'll get 20, despite the original global state likely not even having a variable "b" to access. And you'll still be able to access all the functions, etc. you've defined before this point as well.
Edited to add test code to debug OP's problem.
I put the following code into "junk.lua":
a = 1
local newgt = {}
setmetatable(newgt, {__index = _G})
setfenv(1, newgt)
print(a)
a = 10
print(a)
print(newgt)
The output of it is as follows:
$ lua junk.lua
1
10
table: 0x976d040
This is using Lua 5.1.4. What is the output you're seeing?