LuaPlus: Register function with paramers and one return value? - c++

I don't really understand the system. Using .RegisterDirect("myFunc",myFunc) I can register a function that can't take parameters, but therefore can return a value.
Using .Register("myFunc",myFunc) I can register a function that can take parameters, but therefore can't return any values.
I literally spent days on this issue now and I just can't figure it out. I would really appreciate it if someone would take a look at this.
Here is the documentation. Here is a quick example of how Register and RegisterDirect. Let's say I wanted the Print function to always return the string "hello". How would I do that?
#include "stdafx.hpp"
int Print(LuaPlus::LuaState* pState) {
int top = pState->GetTop();
std::stringstream output;
for( int i = 1; i <= top; ++i ) {
output << pState->CheckString(i) << std::endl;
}
std::cout << output.str();
return 0; // We don't return any values to the script
}
int Get2222() {
return 2222;
}
int main() {
LuaPlus::LuaState* pState = LuaPlus::LuaState::Create( true );
LuaPlus::LuaObject globals = pState->GetGlobals();
globals.Register("Print",Print);
globals.RegisterDirect("Get2222",Get2222);
char pPath[ MAX_PATH ];
GetCurrentDirectory(MAX_PATH,pPath);
strcat_s(pPath,MAX_PATH,"\\test.lua");
if( pState->DoFile(pPath) ) {
// An error occured
if( pState->GetTop() == 1 )
std::cout << "An error occured: " << pState->CheckString(1) << std::endl;
}
LuaPlus::LuaState::Destroy( pState );
pState = nullptr;
getchar();
return 0;
}
Afaik I would have to push the value on the stack and return 1 to indicate that there is something on the stack. But that didn't seem work. I tried to add this to the function to return the number 4:
pState->PushInteger(4);
return 1;
I really hope you can help me out here.

Related

Return struct element from vector c++

I'm new to C++ and I'm trying to return a struct from a vector of structs by using 2 search criteria.
The function find_city is returning me everything from the defined range, regardless of whether it exists inside the vector of struct.
Here's my code:
struct cityLoc
{
int hRange;
int vRange;
int cityCode;
string cityName;
};
vector<cityLoc> cl1;
// the vector has already been preloaded with data
// function to return my struct from the vector
cityLoc find_city(int hRange, int vRange)
{
for (size_t i = 0; i < cl1.size(); i++)
{
if ((cl1[i].hRange = hRange) && (cl1[i].vRange = vRange))
{
return cl1[i];
}
}
}
int main()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j <= 8; j++)
{
cityLoc this_city;
this_city = find_city(i, j);
cout << this_city.hRange << ", " << this_city.vRange << endl;
}
}
return 0;
}
Also, aside from this question, I was previously looking into std::find_if and didn't understand it. If I have the following code, what is the output? How do I modify it such that it returns a struct?
auto it = find_if(cl1.begin(), cl1.end(), [](cityLoc& cl) { return cl.hRange == 1; } );
You have a bug here:
if ((cl1[i].hRange = hRange) && (cl1[i].vRange = vRange))
Those = are assignments, not comparisons! Please enable compiler warnings and you won't be hurt by such obvious typos in future.
std::find_if will return the iterator to the found struct entry if it is successful, std::vector::end() otherwise. So, you should first validate the returning iterator if it is valid or not.
For example:
auto it = std::find_if( cl1.begin(), cl1.end(),
[](const cityLoc& cl) { return cl.hRange == 1; } );
if ( it == cl1.end() )
{
// ERROR: Not found! Return error code etc.
return -1;
}
// And, if found, process it here...
std::cout << it->hRange << '\n';
std::cout << it->vRange << '\n';
The criteria (predicate) part in std::find_if is a lambda expression.

Why does this recursive function return the wrong value?

I continue to run into an issue in building a recursive function where its returned value is different from the value I expect it to return. I'm fairly certain it relates to the recursive nature of the function, but I don't understand what is happening.
int foo(std::string, int = 0);
int main() {
std::string testString = "testing";
std::cout << foo(testString);
}
int foo(std::string givenString, int numberToReturn) {
if (givenString.length() == 0) {
std::cout << "Number to return before actually returning: " << numberToReturn << "\n";
return numberToReturn;
}
if (true) {
numberToReturn++;
}
std::string newString = givenString.erase(0, 1);
foo(newString, numberToReturn);
}
In this minified example, I have function foo with a string and an int with a default value of 0. Given the string "testing" and no integer, I would expect the recursive function to increment numberToReturn for each call and pass the new value to the next call. This must be partly right because if I cout numberToReturn when I reach the base case, I get the expected value (which in this case it would be 7). But as soon as I return that value, it changes to a much larger number (6422160 in my case).
So with that said, why does the number change on return and how do I prevent that change from happening or otherwise return the correct/expected value?
Edit: For anyone with a similar problem in the future, my issue was that each recusrion call must return something, not just the last one. In my case, returning the last line of function foo solves the issue. Not returning something for every function call leads to undefined behavior.
Your function must always end with return, if it doesn't your function will return some random uninitialised value. For example
int foo( int x )
{
if ( x == 0 )
{
return x;
}
foo(x-1);
}
is roughly equivalent to:
int foo( int x )
{
if ( x == 0 )
{
return x;
}
foo(x-1);
return someRandomValue();
}
what you actually want is:
int foo( int x )
{
if ( x == 0 )
{
return x;
}
return foo(x-1);
}

C++ catch error and exit the function

I use try{} catch(){} to handle errors in a function which return a template type.
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}
The function would first call checkIndex to check whether the input is out of range and throw an error if so.
However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly. If I put a return in the catch block, I don't know what to return since it's a template. If I don't, the codes following the catch block will still get executed and therefore return a value.
Is there any way to do that? I'm new to C++ and wondering how people usually do the error handling in this condition? THanks!
However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly.
You can always re-throw the exception after logging
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
throw; // Just re-throw the exception
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}
You can also use optional for this situation. One of idea of this construct was to indicate that value cannot be set correctly because of some mistakes.
std::optional< T > get (int iOffset ) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
return std::optional< T >();
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return return std::optional< T >( a );
}
Using of such function can look like this:
auto result = get( someOffset );
if( result )
{
// correct, processing result
}
One of the easiest way is first to decide: What exactly should your get() return if it cannot return the 'proper' value?
In many cases it is just 0, or -1, or some other special value.
And then the code become very simple:
T get (int iOffset) const
{
T a;
try {
checkIndex(iOffset);
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
a = m_ptBuff[index];
}
catch (char const* msg) {
a = special_value_for_errors;
std::cout << msg << std::endl;
}
return a;
}

Learning recursion: How can I locate a substring index within a string without using find?

I have a recursive function to find the starting index of a substring within a string. I am learning to use recursion, so the find function is not allowed. I believe I have met most of the conditions. This function is supposed to find the correct index in the string. If it is blank it returns -1.
Here is the real problem. If I enter a string "nothing" and search for "jax" it doesn't return -1. I don't understand why. Any help please? Here is the code:
The user would enter string s and t passed into below:
int index_of(string s, string t)
{
int start = 0;
int len2 = t.length();
int index = 0;
if (s == "")
{
return -1;
}
else if (s.substr(1).length() <= t.length())
{
return -1;
}
else if ( s.substr(start, len2) == t)
{
return index;
}
else
{
index ++;
return index + index_of(s.substr(1), t);
}
return -1;
}
There are several problems -- some minor ones, and some quite important ones.
You have two variables, start and index, to indicate "the current position", but one would be enough.
index can only be 0 or 1. Therefore, the way it is currently written, you could easily get rid of index and start altogether.
Important: When, during the final recursion, the end of the string is reached, you return -1 to the previous recursive call. Then, because of the way the recursive calls are done, you add 1 and return that to the previous call, and so forth. The value finally returned is the -1 plus the length of the string. That is why you get strange results.
This comparison
if (s.substr(1).length() <= t.length())
does not make much sense.
Taking all of this into account, here is an improved version:
#include <iostream>
#include <string>
int index_of(
const std::string &s,
const std::string &t,
const size_t index)
{
int len2 = t.length();
if ((s.length() - index) < t.length())
return -1;
else if (s.substr(index,len2) == t)
return index;
else
return index_of(s,t,index + 1);
return -1;
}
/** Overloading, so you can call index_of with just
two arguments */
int index_of(const std::string &s, const std::string &t)
{
return index_of(s,t,0);
}
/** Some test cases. */
int main()
{
std::cout << index_of("hello","ello") << std::endl;
std::cout << index_of("nothing","jax") << std::endl;
std::cout << index_of("hello","llo") << std::endl;
std::cout << index_of("hello","lo") << std::endl;
std::cout << index_of("hello","o") << std::endl;
std::cout << index_of("hello","hel") << std::endl;
}
The best way to learn how to debug problems like this is to work them out on paper. Your example is small enough that it shouldn't take too long. It's pretty clear that you're going to fall into your else case in the first few steps because the strings don't match. So we have:
index_of("nothing", "jax"):
index++; // index is now 1
return 1 + index_of("othing", "jax");
index_of("othing", "jax"):
index++; // index is now 1
return 1 + index_of("thing", "jax");
etc.
Does that help?

return statements when doing Extract Method

Let's say you have a very long method, like this:
int monster()
{
int rc = 0;
// some statements ...
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
// rest of long method...
return rc;
}
and I'm working on skeletonizing the code. I want to extract the dragon slaying part to
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return 0; // ?
}
and replace the code in monster() with a call to handleDragon().
But there is a problem. There is a return statement in the middle of that part. If I keep the part where the return code of handleDragon() is handled, it will keep the litter in the big method.
Besides using exceptions, is there an elegant and safe way to refactor this piece of code out of the monster method? How should these types of situations be handled?
Return 0 from the handleDragon method if the dragon slayer is available:
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
return 0;
}
}
Then back in the monster method, if the return value was greater than zero, return that value, otherwise carry on:
// some statements ...
int handleDragonResult = handleDragon();
if (handleDragonResult > 0) {
return handleDragonResult;
}
// rest of long method...
You should also document the handleDragon method, to explain the value that gets returned.
enum DragonHandled { DHSuccess, DHKing, DHNoKing };
inline DragonHandled askForKing()
{
if (callTheKing())
return DHKing;
else
return DHNoKing;
}
DragonHandled handleDragon()
{
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
return askForKing();
}
cout << "We are saved!\n";
slayTheDragon();
return DHSuccess;
}
int monster()
{
some_statements(...);
DragonHandled handled = handleDragon();
if( handled != DHSuccess )
return handled; // enum to int is an implicit cast
return more_statements(...);
}
Except for a function that returns an actual signed number, I would not return int. If the result has a meaning, define that meaning properly (that is: an enum).
A function does something, and whatever it does, should be visible in its name. So there should be a verb in a function's name (handledragon(), callTheKing()). monsters isn't a verb, it isn't something you can do. If I see an identifier monsters, I'd think it's a container for monsters.
Checking if(x == true) is just useless noise, since if(x) is terser, simpler and just as true.
Couldn't you do this:
int handleDragon() {
int rc = 0;
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
rc = 1;
else
rc = 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return rc;
}
and then:
int monster()
{
int rc = 0;
// some statements ...
rc = handleDragon();
// rest of long method...
return rc;
}
or if you want to do something with the return code:
int monster()
{
int rc = 0;
// some statements ...
int handleDragonReturnCode = handleDragon();
if(handleDragonReturnCode == 0) {
// do something
}
else {
// do something else
}
// rest of long method...
return rc;
}
Is this what you want? On a general note, avoid using magic numbers like 1 and 2 for your return codes. Use constants, #define, or enum.
Concerning return, try to have one exit point from your function. As you have found out, having multiple return statements can make refactoring hard (as well as understanding the logic unless it's really simply).
The question was about the strategy so I think the answer by Richard Fearn is a good one.
To make it into a refactoring pattern it would look something like:
Context: A section in the middle of a larger method is to be extracted.
Problem: The section contains return statements.
Solution:
Extract the code to a new method returning the same type as the larger method.
Find a value of that type that does not mean anything. Call that value CONTINUE.
Add a statement at the end of the new method that returns CONTINUE.
In the larger method test the return value from the new method for CONTINUE. If it is not then return that value.
This would be the principal approach. As the next step you could refactor the return values from the new method to something more meaningful (like in the answer from sbi). And you'd have to find a way to handle the case where the return type isn't a scalar or simple type, returning a NULL object or some such.