Initialise in condition, not assign

I’ve read a lot of code polluted with assignments in condition:

T* p;
if (ptr = source())
{
    ...
}
else
{
    ...
}/

Presumably, it is preferred of someone who is really after shortcuts in code. If you must cut short, reconsider it and at least write this:

if (T* p = source())

It is a perfect shortcut through several features at once: initialisation, condition and scope encapsulation. The scope of p is narrowed to the if-else condition only:

if (T* ptr = source())
{
    ...
}
else
{
    ...
}/

And, it feels and works like using statement in C#. Perhaps that will convince C/C++ legacy crowd ;-)

Thanks to Jonathan Wakely from ACCU for inspiring discussion(s).

Implicit conversion is less than bless

A quick example on how frivolous and to all appearances useful design of a C++ class can kick the rear aspect of your personality hard. In Unicode-enabled code using wchar_t as character data carrier:

#include <comutil.h>
#include <sstream>
int main()
{
   std::wostringstream oss;
   _bstr_t str(L"abc");
   oss << str;
}

Now, remembering that wchar_t has made it into the C++ ages ago, hich version of operator<< is called here?

The example above is equivalent to the following code:

std::wostringstream oss;
_bstr_t str(L"abc");
oss << static_cast<char*>(str);

Possibly, it is because of failure of template argument deduction as specified in C++/14.8.2.1/4. I’d be interested to learn if this interpretation is correct or why, if it is not.

Notes on PyEval_EvalCodeEx

Recently, I tried to figure out what is the actual result of PyEval_EvalCodeEx call from the Python C API. The documentation is less than sparse. Obviously, the function returns result of expression evaluation. The result is returned as pointer to PyObject, but the type has a bit opaque nature, so means nothing without querying and inspecting underlying data.

Luckily, I have received a couple of answers on the Python mailing list as well as from ACCU folks . Here is very quick summary of the PyEval_EvalCodeEx function:

  • first and foremost, know C as well as Python
  • it evaluates an expression, any valid Python expression
  • it wraps the builtin eval()
  • its return value is exactly the same as the return value of an equivalent call to the eval()
  • if the PyObject *co argument was compiled with start argument Py_eval_input denoting a single expression, the function returns value produced as the result of the expression
  • if Py_file_input or Py_single_input compilation mode was used, then the result of will be Py_None
  • it returns PyObject*, so – as Russel Winder suggested – Do type analysis regarding the object being pointed at you have to do it the hard way! PyObject_IsInstance, or if you are eeling really hard :-) PyObject_Type. There is also PyPobject_TypeCheck.

I can’t do it now, but I’m going to check if all those statements are correct.

Preparing for Subversion to Git migration

GEOS is slowly moving to Git, so I decided to clear the Subversion specific settings, namely the svn:keywords. The procedure is quick and based on the commands I used to perform bulk svn:keywords property update.

First, svn:keywords property is removed:

find . -path '*/.svn' -prune -o -type f -print  | xargs svn propdel -q svn:keywords

Next, line consisting of $Id$ keyword is stripped from every plain text file using a tiny script coded in Python:


#! /usr/bin/env python
import fileinput
import re
import sys

def strip_line(filename, rx):
    sys.stderr.write(filename + '\n')
    for line in fileinput.input(filename, inplace=1):
        m = re.match(rx, line)
        if m is None:
            sys.stdout.write(line)
        else:
            sys.stderr.write(line)

if len(sys.argv) < 2:
    sys.exit("Missing filename")

pattern = '^.*\$Id.*$'
rx = re.compile(pattern, re.DOTALL)
strip_line(sys.argv[1], rx)

The script is executed for every file, excluding the working copy admin area in .svn:

for f in `find . -path '*/.svn' -prune -o -type f -print`; do ~/bin/strip_line_regex.py $f; done;

Voila!

Update: Torvalds answers Does GIT has vc keywords like CVS/Subversion?

Python WTF of the day

Update: The rant has been suspended, temporarily.

The code speaks for itself:


>>> class A:
...     def foo(a, ):
...             pass
...
>>>
>>> a = A()
>>> a.foo()
>>> a.foo(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 positional argument (2 given)
>>>

I confess, I am a Python newbie. I climb the rocky curve of the Python C API for the first time trying to write custom Python generators. I still know very little about Python. This is not the last time Python’s bitten me ass.