<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Labix Blog &#187; Lua</title>
	<atom:link href="http://blog.labix.org/tag/lua/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.labix.org</link>
	<description>by Gustavo Niemeyer</description>
	<lastBuildDate>Fri, 09 Jul 2010 19:15:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>The forgotten art of error checking</title>
		<link>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking</link>
		<comments>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:15:59 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=275</guid>
		<description><![CDATA[I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly. The precise wording was: It&#8217;s really amazing how little attention error handling receives in most software development. Even &#8230; <a href="http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly.  The precise wording was:</p>
<blockquote><p>
It&#8217;s really amazing how little attention error handling receives in most software development. Even *tutorials* often ignore it.
</p></blockquote>
<p>It indeed does amaze me.  It sometimes feels like we write code for theoretical perfect worlds.. <i>&#8220;If the processor executes exactly in this order, and the weather is calm, this program will work.&#8221;</i>.  There are countless examples of bad assumptions.. someday I will come with some statistics of the form <i>&#8220;Every N seconds someone forgets to check the result of write().&#8221;</i>.</p>
<p><span id="more-275"></span></p>
<p>If you are a teacher, or a developer that enjoys writing snippets of code to teach people, please join me in the quest of building a better future.  Do <i>not</i> tell us that you&#8217;re &#8220;avoiding result checking for terseness&#8221;, because that&#8217;s exactly what we people will do (terseness is good, right?).  On the contrary, take this chance to make us feel <i>bad</i> about avoiding result checking.  You might do this by putting a comment like &#8220;If you don&#8217;t do this, you&#8217;re a bad programmer.&#8221; right next to the logic which is handling the result, and might take this chance to teach people how proper result handling is done.</p>
<p>Of course, there&#8217;s another forgotten art related to result checking.  It sits on the other side of the fence.  If you are a library author, do think through about how you plan to make us check conditions which happen inside your library, and try to imagine how to make our lives easier.  If we suck at handling results when there are obvious ways to handle it, you can imagine what happens when you structure your result logic badly.</p>
<p>Here is a clear example of what <i>not</i> to do, coming straight from Python&#8217;s standard library, in the <i>imaplib</i> module:</p>
<pre>
    def login(self, user, password):
        typ, dat = self._simple_command('LOGIN', user, self._quote(password))
        if typ != 'OK':
            raise self.error(dat[-1])
        self.state = 'AUTH'
        return typ, dat
</pre>
<p>You see the problem there?  How do you handle errors from this library?  Should we catch the exception, or should we verify the result code? <i>&#8220;Both!&#8221;</i> is the right answer, unfortunately, because the author decided to do us a little favor and check the error condition himself in some arbitrary cases and raise the error, while letting it go through and end up in the result code in a selection of other arbitrary cases.</p>
<p>I may provide some additional advice on result handling in the future, but for now I&#8217;ll conclude with the following suggestion: please check the results from your actions, and help others to check theirs.  That&#8217;s a good life-encompassing recommendation, actually.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Embedding Lua interpreter into RPM</title>
		<link>http://blog.labix.org/2004/03/23/embedding-lua-interpreter-into-rpm</link>
		<comments>http://blog.labix.org/2004/03/23/embedding-lua-interpreter-into-rpm#comments</comments>
		<pubDate>Tue, 23 Mar 2004 06:59:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Patch]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2004/03/23/embedding-lua-interpreter-into-rpm/</guid>
		<description><![CDATA[I&#8217;ve recently committed into the RPM CVS HEAD the internal support for Lua scripts. Please, notice that this is experimental stuff. Why embedding Lua in RPM? Many scripts execute simple operations which in an internal interpreter require no forking at &#8230; <a href="http://blog.labix.org/2004/03/23/embedding-lua-interpreter-into-rpm">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently committed into the <a href="http://www.rpm.org">RPM</a> CVS HEAD the internal support for <a href="http://www.lua.org">Lua</a> scripts.</p>
<p>Please, notice that this is experimental stuff.</p>
<p><b>Why embedding Lua in RPM?</b></p>
<ul>
<li>Many scripts execute simple operations which in an internal interpreter require no forking at all
<li>Internal scripts reduce or eliminate external dependencies related to script slots
<li>Internal scripts operate even under unfriendly situations like stripped chroots (anyone said installers?)
<li>Internal scripts in Lua are really fast
<li>Syntax errors in internal scripts are detected at package building time
</ul>
<p><b>How it works?</b></p>
<p>Just use <tt>-p &lt;lua&gt;</tt> in any script slot (%pre, %post, etc).</p>
<p>For example: </p>
<pre>
%pre -p &lt;lua&gt;
print("Wow! It really works!")
</pre>
<p><b>What is accessible from Lua?</b></p>
<p>The standard Lua library, the posix module (basic system access, by Luiz Henrique de Figueiredo and Claudio Terra), and the rex module (regular expressions, by Reuben Thomas).</p>
<p><b>Macro support</b></p>
<p>Support for Lua macros was also introduced. It means that one can create custom content using Lua macros anywhere.</p>
<p>For example: </p>
<pre>
%{lua: print("Requires: hello-world &gt; 1.0") }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2004/03/23/embedding-lua-interpreter-into-rpm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More additions to APT-RPM Lua interface</title>
		<link>http://blog.labix.org/2004/03/14/more-additions-to-apt-rpm-lua-interface</link>
		<comments>http://blog.labix.org/2004/03/14/more-additions-to-apt-rpm-lua-interface#comments</comments>
		<pubDate>Sun, 14 Mar 2004 06:54:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2004/03/14/more-additions-to-apt-rpm-lua-interface/</guid>
		<description><![CDATA[The APT-RPM Lua interface is constantly being improved. This time, the following functions were added: pkgid() and verid() Return a unique integer identifying a package or a version. verpkg() Returns the parent package of some given version. verdeplist() Returns a &#8230; <a href="http://blog.labix.org/2004/03/14/more-additions-to-apt-rpm-lua-interface">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The APT-RPM Lua interface is constantly being improved. This time, the following functions were added: </p>
<dl>
<dt><b>pkgid()</b> and <b>verid()</b></p>
<dd>Return a unique integer identifying a package or a version. </p>
<dt><b>verpkg()</b></p>
<dd>Returns the parent package of some given version.</p>
<dt><b>verdeplist()</b></p>
<dd>Returns a list of dependencies for a given package, including complete information about it.<br /> 
</dl>
<p>These new functions were introduced to give support for something which is frequently asked by APT-RPM users: the ability to discover which installed packages are not required by any other installed package.</p>
<p>Here is a script using these functions to list these packages. This script will be called list-nodeps, and will be available in the contrib/ directory of the next APT-RPM release. </p>
<pre>
-- Collect dependencies from installed packages
deplist = {}
verlist = {}
for i, pkg in ipairs(pkglist()) do
    ver = pkgvercur(pkg)
    if ver then
        table.insert(verlist, ver)
        for i, dep in ipairs(verdeplist(ver)) do
            for i, depver in ipairs(dep.verlist) do
                deplist[verid(depver)] = true
            end
        end
    end
end

-- Now list all versions which are not dependencies
for i, ver in ipairs(verlist) do
    if not deplist[verid(ver)] then
        name = pkgname(verpkg(ver))
        if name ~= "gpg-pubkey" then
            -- Print package name and version without epoch
            -- (rpm -e friendly <img src='http://blog.labix.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .
            print(name.."-"..string.gsub(verstr(ver), "^%d+:", ""))
        end
    end
end
</pre>
<p>More information about the introduced functions is available in https://moin.conectiva.com.br/AptRpm/Scripting</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2004/03/14/more-additions-to-apt-rpm-lua-interface/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Functions vs. Callable objects in Lua</title>
		<link>http://blog.labix.org/2003/12/20/functions-vs-callable-objects-in-lua</link>
		<comments>http://blog.labix.org/2003/12/20/functions-vs-callable-objects-in-lua#comments</comments>
		<pubDate>Sat, 20 Dec 2003 06:31:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2003/12/20/functions-vs-callable-objects-in-lua/</guid>
		<description><![CDATA[While working on Lunatic Python, I&#8217;ve understood that Lua does specific type checking with lua_isfunction() in some places where a callable type is expected. As a side effect, these places only accept a real Lua function when the callable object &#8230; <a href="http://blog.labix.org/2003/12/20/functions-vs-callable-objects-in-lua">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>While working on <a href="https://moin.conectiva.com.br/LunaticPython">Lunatic Python</a>, I&#8217;ve understood that <a href="http://www.lua.org">Lua</a> does specific type checking with <tt>lua_isfunction()</tt> in some places where a callable type is expected. As a side effect, these places only accept a real Lua function when the callable object might be used. An example of such behavior is, at the time this is being written, the <tt>table.foreach()</tt> function:</p>
<pre>
&gt; obj = {}
&gt; mt = {__call=function() print("Called!") end}
&gt; setmetatable(obj, mt)
&gt; obj()
Called!
&gt; table.foreach({a=1}, obj)
stdin:1: bad argument #2 to `foreach' (function expected, got table)
stack traceback:
        [C]: in function `foreach'
        stdin:1: in main chunk
        [C]: ?
</pre>
<p>The trick used in Lunatic Python to overwhelm this situation was to enclose the custom Python object type inside a real Lua C function closure. This trick might indeed be used anywhere this situation is found. Here are a few functions that allow this trick to be used from inside Lua:</p>
<pre>
static int lwrapcall(lua_State *L)
{
        lua_pushvalue(L, lua_upvalueindex(1));
        lua_insert(L, 1);
        lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
        return lua_gettop(L);
}

static int lwrapfunc(lua_State *L)
{
        luaL_checkany(L, 1);
        lua_pushcclosure(L, lwrapcall, 1);
        return 1;
}

static int luaopen_wrapfunc(lua_State *L)
{
        lua_pushliteral(L, "wrapfunc");
        lua_pushcfunction(L, lwrapfunc);
        lua_rawset(L, LUA_GLOBALSINDEX);
}
</pre>
<p>And here is another implementation, by Alex Bilyk, in pure Lua: </p>
<pre>
function wrapfunc(callable)
    return function(...)
        return callable(unpack(arg))
    end
end
</pre>
<p>Using them one would be able to obtain the effect above as follows: </p>
<pre>
&gt; table.foreach({a=1}, wrapfunc(obj))
Called!
</pre>
<p>Hopefully, in the future the standard Lua library will stop checking for a specific type in such cases, or implement some kind of <tt>lua_iscallable()</tt> checking.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2003/12/20/functions-vs-callable-objects-in-lua/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lunatic Python</title>
		<link>http://blog.labix.org/2003/12/14/lunatic-python</link>
		<comments>http://blog.labix.org/2003/12/14/lunatic-python#comments</comments>
		<pubDate>Sun, 14 Dec 2003 06:27:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2003/12/14/lunatic-python/</guid>
		<description><![CDATA[Lunatic Python is a two-way bridge between Python and Lua, allowing these languages to intercommunicate. Being two-way means that it allows Lua inside Python, Python inside Lua, Lua inside Python inside Lua, Python inside Lua inside Python, and so on. &#8230; <a href="http://blog.labix.org/2003/12/14/lunatic-python">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="https://moin.conectiva.com.br/LunaticPython">Lunatic Python</a> is a two-way bridge between <a href="http://www.python.org">Python</a> and <a href="http://www.lua.org">Lua</a>, allowing these languages to intercommunicate. Being two-way means that it allows Lua inside Python, Python inside Lua, Lua inside Python inside Lua, Python inside Lua inside Python, and so on.</p>
<p>Here are two examples giving an idea about what it does. </p>
<p><b>Lua inside Python</b></p>
<pre>
&gt;&gt;&gt; table = lua.eval("table")
&gt;&gt;&gt; def show(key, value):
...   print "key is %s and value is %s" % (`key`, `value`)
...
&gt;&gt;&gt; t = lua.eval("{a=1, b=2, c=3}")
&gt;&gt;&gt; table.foreach(t, show)
key is 'a' and value is 1
key is 'c' and value is 3
key is 'b' and value is 2
&gt;&gt;&gt;
</pre>
<p><b>Python inside Lua</b> </p>
<pre>
&gt; function notthree(num)
&gt;&gt;   return (num ~= 3)
&gt;&gt; end
&gt; l = python.eval("[1, 2, 3, 4, 5]")
&gt; filter = python.eval("filter")
&gt; =filter(notthree, l)
[1, 2, 4, 5]
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2003/12/14/lunatic-python/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why Lua was embedded into APT-RPM</title>
		<link>http://blog.labix.org/2003/06/13/why-lua-was-embedded-into-apt-rpm</link>
		<comments>http://blog.labix.org/2003/06/13/why-lua-was-embedded-into-apt-rpm#comments</comments>
		<pubDate>Fri, 13 Jun 2003 23:38:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2003/06/13/why-lua-was-embedded-into-apt-rpm/</guid>
		<description><![CDATA[Why embedding at all? APT-RPM is a port of the debian APT tool to RPM systems. Since I&#8217;ve started working in the project, I&#8217;ve been thinking about integrating a higher level language on it. Actually, it&#8217;s pretty easy to explain &#8230; <a href="http://blog.labix.org/2003/06/13/why-lua-was-embedded-into-apt-rpm">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><b>Why embedding at all?</b></p>
<p>APT-RPM is a port of the debian APT tool to RPM systems. Since I&#8217;ve started working in the project, I&#8217;ve been thinking about integrating a higher level language on it. Actually, it&#8217;s pretty easy to explain this intention. How many times have you seen distributions hacking a project to fix some misbehavior specific to their environment, or wanting some very specific functionality, which wouldn&#8217;t fit in the general context of the upstream project? Attaching an external language allows you to plug these features, without affecting how the project is conducted. Also, I&#8217;m a fan of the productivity and flexibility offered by high level languages. </p>
<p><b>Why Lua?</b></p>
<p>One might think I&#8217;ve used Lua just because I live in the same country as its core developers (Brazil), but that&#8217;s not the case. Indeed, I&#8217;ve done a pretty intensive research about embeddable languages before choosing Lua. I was looking for a fast, and small language. When you have a library which has about 500kb, you can&#8217;t embed a large interpreter to extend the functionality, otherwise you&#8217;d be extending the interpreter, not the library. One might think that the interpreter library would be in the system anyway, so that wouldn&#8217;t be a real problem. Unfortunately, that doesn&#8217;t apply to APT-RPM, since it is used in small systems, and in installer environments. The current Lua interpreter is still under 100kb, and is very fast if compared to other interpreters. I really think the Lua interpreter has no current competitors in that specific area. </p>
<p><b>Slot code example</b></p>
<p>To give you an idea about how comfortable it is to work that way, I&#8217;ve recently introduced the possibility of passing generic filenames to the &#8220;apt-get install&#8221; command. To do that, I&#8217;ve introduced a new slot in the APT-RPM core, which is called when the data entered is not found as an available package name. Notice that this slot is generic, and works for other kinds of parameters, besides filenames. In the following slot code, notice that the Lua interface has been wrapped into a more useful API for the APT-RPM environment. </p>
<pre>
_lua-&gt;SetDepCache(Cache);
_lua-&gt;SetDontFix();
_lua-&gt;SetGlobal("argument", Argument);
_lua-&gt;RunScripts("Scripts::Apt::Install::TranslateArg", false);
const char *name = _lua-&gt;GetGlobal("translated");
_lua-&gt;ResetGlobals();
_lua-&gt;ResetCaches();
</pre>
<p><b>Plugin code example</b></p>
<p>With the slot code above, developing the filename translation plugin was very straightforward. Of course, some kind of database containing the filename information was needed. I&#8217;ve used a compressed textfile, containing thousands of pairs like &#8220;filename packagename&#8221;, one per line. And here is the final plugin. Can you imagine how much code it&#8217;d take if implemented in C  , the core language of APT-RPM?</p>
<pre>
-- Data sample:
--   argument = "/usr/bin/lua"
--   contents = "/var/state/apt/Contents.gz"
--   translated = "newname" 

if string.sub(argument, 1, 1) == "/" then
    contents = confget("Dir::State::contents/f")
    if string.sub(contents, -3) == ".gz" then
        file = io.popen("zcat "..contents)
    elseif string.sub(contents, -4) == ".bz2" then
        file = io.popen("bzcat "..contents)
    else
        file = io.open(contents)
    end
    len = string.len(argument)
    for line in file:lines() do
        if string.sub(line, 1, len) == argument then
            _, _, path, name = string.find(line, '(%S )%s (%S )')
            if path == argument then
                translated = name
                break
            end
        end
    end
    for line in file:lines() do
        -- nothing, just don't break the pipe
    end
    file:close()
end
</pre>
<p><b>More information</b></p>
<p>For more information, have a look at https://moin.conectiva.com.br/AptRpm and https://moin.conectiva.com.br/AptRpm/Scripting</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2003/06/13/why-lua-was-embedded-into-apt-rpm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
