9. February 2023

How to call Rust functions from Python, Ruby and Zig

Rust language is great for creating libraries and drivers which can be consumed by other languages like Python, Ruby or Zig.

Let’s consider following Rust application Cargo.toml:

[package]
name = "rustlib"
version = "0.1.0"
edition = "2021"

[lib]
name = "rust_lib"
crate-type = ["dylib"]

File src/lib.rs:

#[no_mangle]
pub extern "C" fn add(left: usize, right: usize) -> usize {
    left + right
}

The next step is to build the library:

cargo build --release

The output library is stored in ./target/release/librust_lib.so

Python

Invoking the add function from Python is very easy:

import ctypes
lib = ctypes.CDLL("./target/release/librust_lib.so")
lib.add(1,2)

Ruby

In case of Ruby we will need ffi gem.
Installation on OpenSuse:

sudo zypper install ruby3.1-rubygem-ffi

Ruby code:

require 'ffi'

module MyLib
  extend FFI::Library
  ffi_lib './target/release/librust_lib.so'
  attach_function :add, [ :int, :int ], :int
end

puts MyLib.add 1, 2

Zig

Zig will require little bit more stuff. We need to generate C headers from Rust, which then can be loaded to Zig. Install cbindgen for the conversion:

cargo install cbindgen

Generate header file from the library.

cbindgen --lang c --output rustlib.h

Create Zig application in zig2rust:

const std = @import("std");
const rustlib = @cImport(@cInclude("rustlib.h"));

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const result = rustlib.add(1,2);
    try stdout.print("Result is {d}.\n", .{result});
}

Compile Zig application:

zig build-exe zig2rust.zig -I. -l target/release/librust_lib.so

Run the application:

./zig2rust

29. June 2013

True/False gotcha Python vs Ruby vs PowerShell vs NodeJS vs PHP

Evaluation of conditions is very important part programming. True is ture, false is false…

Or not? It might surprise you, but not all languages evaluate numbers, empty strings or empty arrays in the same way.

Let’s examine several technologies. Python, Ruby, PowerShell, NodeJS and PHP.

Here is small code written in Python:

def test(value):
    if value:
        print "True"
    else:
        print "False"

test(0)
test(1)
test("")
test([])
test({})

Here is similar code written in Ruby:

def test(value)
    if value
        print "True"
    else
        print "False"
    end
end

test(0)
test(1)
test("")
test([])
test({})

Let’s compare it to PowerShell:

Function Test($value) {
    if ($value) {
        Write-Host "True"
    } else {
        Write-Host "False"
    }
}

Test(0)
Test(1)
Test("")
Test(@())
Test(@{})

Same logic in JavaScript for NodeJS:

function test(value) {
    if (value) {
        console.log("True");
    } else {
        console.log("False");
    }
}

test(0);
test(1);
test("");
test([]);
test({});

Code in PHP:

<?php 
function test($value) {
    if ($value) {
        echo "True";
    } else {
        echo "False";
    }
}

test(0);
test(1);
test("");
test(array());
test(array());
?>

Results are little bit surprising:

 

Python Ruby PowerShell NodeJS PHP
0 False True False  False False
1 True True True True True
“” False True False False False
[] False True True  True False
{} False True True  True False

1. June 2013

GitLab: Could not read from remote repository

When you try to push to GitLab you may end up with following error message:

fatal: Could not read from remote repository.
Please make sure you have the correct access rights
 and the repository exists.

It’s not very clear what’s real cause. You may check the permission, but it might not solve the problem.

One quick solution could be just restart of GitLab service. It still might not help.

Let’s learn some mechanics of GitLab.

You send data via ssh to GitLab server. When authentication by key is succesfull then server will invoke gitlab-shell. This will shell send request to web interface of GitLab. Yes, web interface. Then it will allow you to access git repository.

Schema:

git -> ssh -> sshd -> gitlab-shell -> gitlab web

The problem described in the beginning of this article is between gitlab-shell and gitlab-web. Most likely shell is not able to access gitlab web. URL is broken or host configuration is incorrect or port is not reachable.

Just go to gitlab-shell project and open file config.yml. You’ll see something like this:

gitlab_url: "http://localhost:80/"

Test this URL directly on server e.g. by links:

links http://localhost:80/

You may need to change hostname or port or add base directory to URL. Fix the URL so the gitlab-shell is able to access web interface. Restart gitlab service and try to push again.

Further discussion about this and similar problems is available at github.

8. May 2013

Vim mode in Cloud9 IDE

Cloud9 IDE is cloud base IDE for NodeJS, Python, Ruby or PHP projects.

The cool thing about this IDE is that code editor has support for Vim mode (it also supports Emacs) :)

vim-cloud9

Go to View, Keyboard Mode and select Vim.

Voila you can use many Vim features, like indentation by >> or many others.

Here is offical video from Cloud9 Youtube channel: