Wednesday, July 29, 2020

Commas have high precedence in PowerShell even when intended for array subscripting

I recently received a confusing error message from PowerShell regarding an expression like this:

$Some2DLongArray[$SomeIndex + 1, 0]

Method invocation failed for op_Addition because Object[] has no such method. Indeed, there is no operator that will add a single value to an array (from the left at least). But there shouldn't have been any object array involved here. Apparently PowerShell interprets the comma as delimiting elements of the array literal 1, 0 then tries to add that array to $SomeIndex. To get my expected interpretation of using $SomeIndex + 1 as the first dimension's index and 0 as the second's I had to enclose $SomeIndex + 1 in parentheses.

Tuesday, July 28, 2020

Windows feature updates may remove support for old file shares

I recently updated a Windows 10 machine with the newest feature update. Afterward it was unable to open a folder shared from a Windows 95 VM. Opening the share produced an error about SMB 1.0 no longer being supported. Fortunately it is possible to reenable support for the old protocol by installing an optional component. In the Windows Features dialog (run optionalfeatures), enabling "SMB 1.0/CIFS File Sharing Support" or specifically "SMB 1.0/CIFS Client" made the share usable again.

Friday, July 17, 2020

The Woocommerce gettext hook receives already-escaped HTML

Today I needed to change the "Billing & Shipping" label on a Woocommerce checkout page. Conveniently there is a gettext hook to which functions can be attached to postprocess the results of translation. This thread has an example, but just adjusting the target text did not work. It turns out that the first $translated_text parameter receives HTML-escaped text, so I actually needed to compare against "Billing & Shipping".

Monday, July 13, 2020

Creating tables with SQL in phpPgAdmin

I'm working on setting up a PostgreSQL database hosted on Namecheap's shared hosting, which seems to only allow access through the phpPgAdmin web app. I'm testing things in a local PostgreSQL instance with a different interface and copying the table definitions to the shared server as SQL "create" commands when ready. I first tried pasting it into the box on the "SQL" tab of the database object, but phpPgAdmin seems to wrap the command in a way that makes it invalid. However, there is a small "SQL" link in the far upper right of the page that produces a new window. Arbitrary commands can be successfully run from there.

Saturday, July 11, 2020

Invoking an object as a function in Kotlin JS

Some JavaScript libraries provide function objects with additional members. Expressing these as Kotlin objects in external class declarations is somewhat difficult. They can be given an operator fun invoke and called like a function using method call syntax, but the compiler will produce a call to an invoke method that doesn't exist. That could be re-@JsNamed to call and appear to work in some cases, but it's not really the right thing to do since call has the special behavior of setting this.

The expected approach seems to be to drop to weak typing by reinterpreting the object as a function. The class can be given an inline extension operator invoke along these lines:

inline operator fun Express.invoke(): ExpressApp {
    return this.unsafeCast<() -> ExpressApp>()()
}

Alternatively the receiver can be treated as the dynamic type:

inline operator fun Express.invoke(): ExpressApp {
    return this.asDynamic()() as ExpressApp
}

Thursday, July 9, 2020

PostgreSQL users may need to be added to databases manually on Namecheap

I recently set up a PostgreSQL database on Namecheap's shared hosting platform. The cPanel interface allowed me to create the database and a user for it, but even after adding the user to the database my app was denied access to the tables. It seems that cPanel didn't actually grant the new user any permissions on the database. To do that, I had to go into phpPgAdmin, go to the database, switch to the Privileges section, and use the Grant link to grant the user privileges.

Wednesday, July 8, 2020

Watch out for returns inside inline functions

Blocks passed to Kotlin inline functions can return from the function calling the inline one - this is one of the advantages of inline functions. However, the inline function should be very careful that it's safe to return successfully (not just exceptionally) after calling a block passed to it. Today I was stumped for a bit on a database transaction wrapper function that mysteriously failed to issue the "commit" command after running the block. The block passed to it contained a plain return statement, which exits the entire enclosing function, when I meant to return a value from the block. The immediate fix was to change the return to return@theInlineFunction, but to avoid the issue in the future I adjusted the inline function to issue the commit in a "finally" block after checking that the "catch" block was not triggered by a crash in the block.