WRT this question -- I got something working by getting the current 'prompt' function as a string and writing a new .ps1 file defining 'prompt'.
In writing the new function, I put the functionality I want to add in a try/catch block, and write the existing prompt functionality into a finally block.
Not at all ideal, but it works in v2.0. When I run it in v3.0, I get an exception:
"Control cannot leave a finally block"
Is there any way to for a script to ask the host for a certain version's behavior?
Thanks for any insights.
Current 'prompt' function consists of:
return " > "
I want to add some functionality to the prompt function, so I write a new temp.ps1 file. I add my functionality in try/catch block, and include the existing in a finally block.
The temp.ps1 looks something like:
function global:prompt {
try {
pushd
}
catch {
$errors[0] | fl * -force
}
finally {
return " > "
}
}
This works as expected in v2, causes the "Control cannot leave..." error in V3.
If you plan to keep using Powershell V3, you cannot have a return statement in your finally block. See Page 6 of Windows Management Framework 3.0 Release notes: (You shouldn't need a return value there anyways)
http://download.microsoft.com/download/5/2/B/52B59966-3009-4F39-A99E-3732717BBE2A/WMF3%200%20Beta%20Release%20Notes.docx
Related
I use VLC media player 1.1.9 on Ubuntu 11.04. I'm trying to experiment with lua extensions for VLC; so I've added the file test.lua in ~/.local/share/vlc/lua/extensions/, which has only these two lines:
fps="25.000"
frame_duration=1/tonumber(fps)
When I run vlc with verbose output for debugging, I get (edited to split on multiple lines:):
$ vlc --verbose 2
...
[0xa213874] lua generic warning: Error loading script
~/.local/share/vlc/lua/extensions/test.lua:
.../.local/share/vlc/lua/extensions/test.lua:2:
attempt to call global 'tonumber' (a nil value)
...
Now, as far as I know, tonumber as function is part of Lua5.1 proper (Lua 5.1 Reference Manual: tonumber) - and on my system:
$ locate --regex 'lua.*so.*' | head -4
/usr/lib/libipelua.so.7.0.10
/usr/lib/liblua5.1.so
/usr/lib/liblua5.1.so.0
/usr/lib/liblua5.1.so.0.0.0
... apparently I do have Lua 5.1 installed.
So, why do I get an error on using tonumber here - and how can I use this (and other) standard functions in a VLC lua extension properly?
Documentation is sparse for VLC Lua extensions to say the least but I did find an example in the github vlc repository here: https://github.com/videolan/vlc/blob/master/share/lua/extensions/VLSub.lua
Judging from that example it appears you need to supply some basic event functions for your addon for VLC to call into when certain events happen. Some of the obvious callback handlers I've noticed:
descriptor, this should return a table that contains fields describing your addon.
activate, this seems to get called when you activate it from view menubar.
deactivate, called when you deactivate the addon from view menubar.
plus a couple of other functions like close and input_change which you can guess what they're for.
From my brief testing done on VLC 2.0.8 under Win7 it appears VLC loads the lua extension using an empty sandbox environment. This is likely the reason you're getting nil for tonumber and I'm betting none of the other standard lua functions are accessible either when you try to perform computation at this global scope.
However, if I move that code into one of the event handling functions then all those standard functions are accessible again. For example:
function descriptor()
return
{
title = "Test Ext";
version = "0.1";
author = "";
shortdesc = "Testing Lua Extension";
capabilities = {};
description = "VLC Hello Test Addon";
}
end
function activate()
print "test activating"
local fps = tonumber "25.000"
local frame_duration = 1 / fps
print(frame_duration)
return true
end
-- ...
That prints out what you would expect in the console debug log. Now the documentation (what little there is) doesn't mention any of this but what's probably happening here is VLC is injecting the standard lua functions and vlc api table into the sandboxed environment when any of these event handlers get called. But during the extension loading phase, it is done in an empty sandbox environment which explains why all those lua function calls end up being nil when you try to use it at the outter most scope.
I recommend cloning the VLC source tree from github and then performing a grep on the C source that's embedding lua to see what VLC is really doing behind the scenes. Most of the relevant code will likely be here: https://github.com/videolan/vlc/tree/master/modules/lua
Probably some extension script installed in your system overwrites the function and the Lua interpreter instance is shared between all extension scripts, so you end up not being able to call the function if that script is called before yours.
As a quick workaround, Lua being dynamically typed, you can still do things like:
1 / "25.000"
and the string will be coerced to a number.
Alternatively, you can define a tonumber equivalent like:
string_to_num = function(s) return s + 0 end
This again relies on dynamic typing.
I'm using GroovyConsole to evaluate scripts I get from external sources. So the code to evaluate is dynamic and I don't have control over it. Actually is written into a database and I have to read it as a String. Not perfect, but that's how it is.
What I'm doing right now:
private GroovyShell shell
def processScript( def script){
if (script) {
try{
shell.evaluate (script, 'some_random_name')
}catch( e ){
log.warn "Could not process script: $e"
}
}
}
This usually works. But now we got a large script (~3000 LOC) and it throws java.lang.RuntimeException: Method code too large! because the script is larger than 64K.
I tried to dump the script into a file and use a BufferedReader, but it throws the same Exception.
So is there a better way to evaluate dynamic Groovy code from within a Groovy method?
The problem is your script reach the java limit for a method. I think the only solution is to split your script in many scripts in some way.
See this answer
I have this code running inside Rhino under Linux. The file doesn't exist.
try {
var u = readFile("/tmp/wtf");
print(u);
} catch (e) {
print("error!");
}
The code in the 'catch' doesn't run, even though the file definitely isn't there. I just get a blank value assigned to 'u'. Is this normal?
Are there other situations (besides a file missing) where the catch would run?
Could I differentiate an empty file from a missing one without invoking some other function? (I realize Rhino gives me access to most of the standard Java libaries).
Just want to confirm that readFile is always synchronous?
I can't find anything much on SO or MDN about how readFile works. Any insight appreciated.
Say i have two files:
One is called mainFile.lua:
function altDoFile(name)
dofile(debug.getinfo(1).source:sub(debug.getinfo(1).source:find(".*\\")):sub(2)..name)
end
altDoFile("libs/caller.lua")
function callBack()
print "called back"
end
doCallback()
The other called caller.lua, located in a libs folder:
function doCallback()
print "performing call back"
_G["callBack"]()
end
The output of running the first file is then:
"performing call back"
Then nothing more, i'm missing a line!
Why is callBack never getting executed? is this intended behavior, and how do i get around it?
The fact that the function is getting called from string is important, so that can't be changed.
UPDATE:
I have tested it further, and the _G["callBack"] does resolve to a function (type()) but it still does not get called
Why not just use dofile?
It seems that the purpose of altDoFile is to replace the running script's filename with the script you want to call thereby creating an absolute path. In this case the path for caller.lua is a relative path so you shouldn't need to change anything for Lua to load the file.
Refactoring your code to this:
dofile("libs/caller.lua")
function callBack()
print "called back"
end
doCallback()
Seems to give the result you are looking for:
$ lua mainFile.lua
performing call back
called back
Just as a side note, altDoFile throws an error if the path does not contain a \ character. Windows uses the backslash for path names, but other operating systems like Linux and MacOS do not.
In my case running your script on Linux throws an error because string.find returns nill instead of an index.
lua: mainFile.lua:2: bad argument #1 to 'sub' (number expected, got nil)
If you need to know the working path of the main script, why not pass it as a command line argument:
C:\LuaFiles> lua mainFile.lua C:/LuaFiles
Then in Lua:
local working_path = arg[1] or '.'
dofile(working_path..'/libs/caller.lua')
If you just want to be able to walk back up one directory, you can also modify the loader
package.path = ";../?.lua" .. package.path;
So then you could run your file by doing:
require("caller")
dofile "../Untitled/SensorLib.lua" --use backpath librarys
Best Regards
K.
For debugging purposes it would be great to be able to see just what you are getting back from the map method. Is this possible in ruby?
To do this in the Mongo shell, you can define you own debug version of the emit() function to print trace information.
function emit(k, v) {
print("emit");
print(" k:" + k + " v:" + tojson(v));
}
Check out Troubleshooting MapReduce in the MongoDB docs for more info.
I know the Mongo documentation recommends defining your own emit function, but I find it easier to instead use print() directly in my map- and reduce-functions while I watch Mongo's log.
Just put any print()'s in your code, run tail -f /var/log/mongodb/mongodb.log, then run your code. You should see the print()'s output to the console.
Here's a few of the benefits:
Ability to debug the reduce() function – defining your own emit() doesn't help here
No need to define the emit() function every time you fire up the mongo console
Write your code in your editor instead of going back and forth between console and IDE
Ability to do code generation and variable interpolation in your native language