/tinyletter

The Programs of the Week of Yom Kippur

This Week’s Program: Sep 25 - Sep 29

Happy Friday and Gut Yuntiff! Last week, I discussed the proper pronunciation of “gobject” (with a hard g as in goblin). It occurred to me today that pronouncing it like the character Gob from Arrested Development would be quite funny as well — “jobe-ject”.

This week I switched gears and moved deeper into the gstreamer module, using some of the new functionality I’ve written in the ffi/unsafe/introspection module that deal with bridging the world of gobjects to the world of racket/class.

The result is an in-progress rewrite of the building blocks of Overscan. I want to make a good Racket binding for GStreamer that feels like conventional Racket. Feels like I’m progressing toward that goal.

c96c04aee8e5c83122bc9e74b7641365d52b83bb

With all the tools from the previous weeks at my disposal, I create gst-object%. This is a subclass of gobject% that uses last week’s make-gobject-delegate for the heavy lifting. This class is the base class for most of GStreamer’s domain. Now it’s provided as a nice tidy Racket class, complete with a contract enforcing its method boundaries. Contracts, in this case, are pretty important. Contracts, if you recall, are a way to express assertions, and they’re used a lot throughout Racket for making easy-to-follow error messages. The reason why I went through all that hullabaloo with the introspection module, was so that I can bring the usage of GStreamer closer to what a typical Racket developer would expect. Here’s the first step of that!

f3350fff9f8218b45aaa50327a693493d7d74002

And the second step has me rewriting element% and element-factory% to inherit from gst-object%.

fa02cedede95af12635078f0ff77d8db12d2fdcb

Now here’s a funny thing about writing contracts on classes: those contracts are only enforced when they’ve been explicitly placed in the entry point for dynamic dispatch. In other words, within the element.rkt module, those functions that return object instances will not have their return values subject to a contract. This makes the element & element-factory relationship particularly tricky. The element-factory% class has methods that construct element% instances. And element% has a method to retrieve the element-factory% that constructed it. This is a recursive thing, and can’t easily be expressed with the contract system. Racket provides a few different mechanisms for working with contracts to make this easier, but the one I decided to reach for was instanceof/c. This lets me express that a function should return a contract for a class where I would otherwise not have access to the class itself, thereby making sure the contract is in the path of dynamic dispatch.

Got all that? No? Yeah… I have a hard time explaining it. The main thing to take away here is that contracts are good because they make really useful error messages. It’s important the contract is applied when you need the value to be checked.

e4bc050da879207f85cbc37c687bfa7d8dc77ade

I write my own contract. gi-enum-value/c is a contract that accepts an introspected Enum and recognizes its values.

01ac7888ad6ebe7d7400b2e984d69c56fd174cfb

Here’s even more contracts on GStreamer objects! No invalid data EVER! pad% and the spookier ghost-pad%!

8eac317d67177c4718bbd0302d2a85d619d7233c

Recursion and OOP!

87ba946b29bee9123f4efa232f3345b53ec4dd0f

The bin% is back, with the new OOP powered factory function, bin%-compose!

The rewrite of the GStreamer module is now well under way and I’ve got a bunch of ideas here. I can’t wait to get back into Overscan, but I’m happy to be making progress on something that might see a ton of utility outside of Overscan itself.

— Mark