Tag Archives: Productivity

New Year’s Resolution

These are the first lines I write in this new year, 2017. I want to start with wishing you all a very good and successful year. How strange is it. On New Year’s Eve we look back, while on New Year’s day we make plans and start with our New Year’s resolutions.

Some things will start, some have ended and some continue. For most of us, Uniface is one of those continuing. As I wrote before, sometimes I wonder how long it shall. But on the other hand, why care. There are thousands of software development tools. Most of them are bigger (whatever that may be) and perhaps some better than our beloved Uniface. The concept of programming is, from a certain point of view, always the same. Sure, you need to learn. You quit being a Uniface senior to become a junior in something else. You will enter a whole new world, with new and probably many young software developers. And between these hipsters you are the oldest junior they have ever seen. Wow, interesting, isn’t it? Your New Year’s resolution can be becoming a junior again!

In a previous blog I’d bet you a beer. I wrote about this company where I once worked. They tried several software development platforms. Maybe they found something else more tempting. Eventually they did choose Uniface. You did not expect that, did you! To be honest it was a close call. Right on time Uniface invited the management for a lab visit in Amsterdam. Uniface product management listened and that did some amazing magic.

But software development isn’t about magic. No fairy tale with software generating magicians. We all know that. It’s just hard work. One of the most heard complaints is the lack of standard components or add-ons in Uniface. The management of the mentioned organisation also asked this to the Uniface product management. Why do we need to build everything by our self? Why can’t we download standard solutions instead of building them?

The answer is simple: just because…

  1. Your problem is unique, no one ever had it before
  2. It’s been built, but the solution is too specific
  3. Or the solution is built in a previous Uniface version (what the f…, Uniface is upward compatible!)
  4. Or the quality is poor, there is no documentation, there is no source code available or someone wants money for it (and you believe software should be free)
  5. Someone built it before, but did not share it with you.

Is this a problem? Yes, it is. Can we fix it? Yes, we can. And I believe it’s simple. Whenever you think ‘Hey, why can’t I just find this on the web?’, do the following:

  1. Look once again, perhaps it is somewhere around
  2. Design the most generic solution
  3. Build it
  4. Test it
  5. Write some documentation
  6. And…. share it.

Maybe it’s a good New Year’s resolution. Emphasize your Uniface seniority and build to share. How? Where? Who? After reading all of the reactions on my previous posts I have a plan. I am working on it and I’ll explain it to you in the next posting.

Happy new year!!!!

Make some noise!

In my previous blog post I told you about my worries. I was thinking about it and even talked to a few of you about it. It reminded me of something that happened to me once. A few years ago I was hired by an organisation. I was just one of the Uniface pro’s. Besides Uniface they used another development platform. I witnessed something very interesting, let me share this with you.

Both disciplines had their own room. In one room all went well, a dozen men worked in silence, behind a closed door they achieved their goals on time and within budget. The applications they maintained were very stable and performed as expected. The other room on the other hand was very lively, the walls were filled with all kinds of merchandise. The young developers had all kinds of technical issues, played arcade games in their breaks and drank beer after work.

Can you guess in which room the Uniface developers worked? Easy one, I know. If you can guess the next answer, I’ll buy you a beer. Which platform was preferred by the management?

I am afraid this is going to cost me a fortune on beer. We all know the answer. Of course, the other guys did a great job. I am, like most of us, too negative about them and the tooling they use. The reason they were not that productive was caused by the tools they used. But did they win?

Change the point of view. Let’s say you are the management of a company. The company depends completely on a few Uniface applications. Very stable and low on maintenance costs. In the near future you expect major changes in the organisations strategy and the markets are changing rapidly. You need to invest in new applications and/or change the existing ones. Are you going to use Uniface or go for something completely new? Choosing Uniface is the rational choice, isn’t it. Imagine, you have all these experienced guys (sorry ladies, but this is a man’s world…). But you never hear them. Sometimes you wonder if they even exist! How do you know if they use modern techniques? And what if you need a dozen more of these pro’s? Where and how can you find them? When you consult google.com you’ll find all kinds of software warehouses to deliver you support on that other tool, while on Uniface all you find in the top 10 is Uniface itself.

If I had to give advice to this management, my advice would be to choose this other tool. Regardless which tool. Being a Uniface developer, as I am, I can tell you this hurts a lot. But it’s just a rational thing. Or isn’t it?

This reminds me. Once in a small village in The Netherlands the only shop closed down. All inhabitants did their grocery in the large supermarket in the adjacent city. Quiet normal, I guess you see this everywhere in the world. The next day an alderman announced in the newspaper that it would be a good idea to not only close the small shop, but also close the complete village. If the inhabitants loved the city to do their grocery, why not go and live there. This action did not save the local shop. But what if this one guy achieved to create a kind of movement. Let’s say, he achieved to motivate some entrepreneurial people. With this small group they could create new business for the local store. Instead of competing with the large competitor, focusing on the strengths. Sometimes you need the help of a community. Today, the strength is the community!

All successful tools I know have communities. Some very successful tools even are created by the community! A product community can be a partner or a critic ally for the company, but always fight on the same side. But, where is the Uniface community? All I see is a great product and a website (uniface.info) with lots of fans. But that is not a community! It is something created by Uniface. I want to create a real Uniface community.  I truly believe we have the strength to unite and make the difference!

You can either participate or wait behind a closed door and I believe I can hear some melancholic seventies music. Let’s make some noise…. Let the world know we are here…. In my next blog I will share my ideas and plans with you all. Do you have idea’s? Please contact me  🙂

Uniface 10: The new procedural declaration of component variables

For Uniface 10 we are constantly reviewing and redefining old concepts, aiming for consistency and reusability while looking for new ways to improve your developing experience and enforce good development practices. This is what the new procedural declaration of component variables is all about.

If you are a developer coming from older Uniface versions you probably are familiar with the ‘Define Component Variable’ form, that allows the creation of variables with component scope and an optional display format. You certainly also know how to declare local variables using the variables block in your triggers and modules. In that case, you might have wondered while accessing the ‘Go To -> Component Variables…‘ menu, selecting the data type from a dropdown list, entering a display format and filling a couple of optional fields… Why can’t I do this from my code, like with local variables?

There are some advantages in the form approach, but the truth is that variables declaration is a fundamental part of coding, as it is the concept of variables scope. It is not only logical but even expected for new developers that variable definitions at component level have component scope. Furthermore, is it a more efficient method of defining and inspect variables. If you think that way, congratulations: You got it! If you are not convinced yet, please keep reading.

In version 10 (10.1.03 and higher) component variables are declared using the ‘variables’ block in the Declarations container of a component. You may declare as many blocks as you want, taking in account that variable redefinitions are not allowed by the compiler. The display format definition takes place -optionally- in the declaration itself, so it looks like this:


variables

DataType {DisplayFormat} VariableName {, VariableName2 ... {, VariableNameN}}

endvariables

The display format is defined using the ‘DIS(<format>)‘ syntax, as it used to be in the ‘Define Component Variable‘ form. You can find extensive documentation about display formats in the Uniface Library. As for the missing fields ‘Description‘ and ‘Comments‘… Well, nothing better than in-code comments to describe our variables.

An actual example of component variables block could be:


variables

string                         vCity, vCountry

string DIS(Mr./Ms. ??????????) vFormattedName         ;- Formatted name for official notifications

date   DIS($NLS(MEDIUM,DATE))  vStartDate, vEndDate   ;- Start/End of contract

float  DIS(9999999P99 US$)     vSalary                ;- Net salary in US dollars

endvariables

Simple, isn’t it? But here is the best part: since component variables are declared procedurally, you can use all the precompiler directives to generate, influence and include component variable declarations. Move your variables block to an include proc to make it reusable. Use the #for directive to quickly generate variables. Make use of definitions to avoid typing complex display formats and ensure consistency between components. Create a snippet library with display formats to quickly insert them into your code.


variables

;- Predefined variable declaration for error handling:

#include MYLIB::ERROR_VARS                 

#for CPTVAR in (NAME,SURNAME,CITY,COUNTRY)

string v<CPTVAR>                      ;- Generate component variables for customer data

#endfor

string <IBAN_FORMAT> vAccount           ;- Predefined printed format for IBAN code (IBAN ???? ???? ???? ???? ????)

endvariables

If you are still hesitant don´t despair: We keep working on great ideas to make code editing faster and easier, as well as providing code and compiled objects information on the editors. But more about that in another blog post…

In the meantime, leave us a comment with your thoughts about the new system! What do you like? What can be improved? How would you make the best use out of it?

Loading loads of Glyphs

As a software developer, every once in a while you find yourself performing a tedious manual task for some hours. As it seems to be something you need to do only once, it does not seem to be worth automating the task. But then later it turns out that you have to do it again. So you make a quick and dirty tool. And then later a colleague has to do the same thing and asks if you have an efficient way of doing it. So you make your tool a bit nicer so people other than you can use it.

For me this happened for the task “load a very large number of image files into Uniface Glyphs”.

So here I present you my tool.

It allows you to select a folder on your disk, then it presents you all the files that are in the folder. You select the files you want to convert and press the button. Occurrences are created in the Uniface Glyph table. Files in an unsupported format are marked yellow, Glyph names and descriptions that are too long are also marked in yellow. Make your changes and press the next button and all your Glyphs are stored and compiled.

Now we can perform a task that used to take hours in a few minutes. (Admittedly you don’t have to do this very often but it is really boring task when you do need to do it!)

The attached Uniface export is for Uniface 9.7. With some adjustments it should also work with older Uniface 9 versions. You need to have a DICT model in your repository (have umeta.xml imported).

http://unifaceinfo.com/download/6470/

Disclaimer:

This tool is not part of the Uniface product and therefore not in support. It also uses some code that is not officially supported and that is subject to change without notice. Please feel free to change the tool to your own requirements.

Glyphmaster

NB:
Have a look at what I did around the selection of the folder:

  • You can either type the name,
  • Or select it from a dialog when you press the button,
  • or select it from your history using the dropdown.

 

Inheritance: Why Uniface 10 will save developers a lot of time

As many of you may be aware, we have – for some time – been working on the new version of Uniface, v10. As befits a major version increment, there are quite a few changes in the development environment, as well as to some of the concepts of Uniface. Today I would like to describe one such change, that should help to make development more obvious.

Inheritance, from model to component, has always been a cornerstone of developing an application with Uniface. The model contains the global definition and the component the external variation, the external variation taking a higher precedence over the model when coming to compile. Let’s examine this concept in a little more detail in the area of local procs.

Imagine, if you will, that when using version 9 you have entries defined in the Local Procs Module trigger of a modelled field, and that the field is painted on a component. When you compile and run the component, any calls you have made to the local proc will cause you to execute the entry defined in the model. Now, if you were to create an external variation of the proc and run the component again, you would expect external variation to be used. So given this, the external variation wins out over modelled procs, right? Well, no, not quite! If I were to now paint a new modelled field with yet another version of the local proc defined and lower down the compile order of the component, what happens could be seen as unexpected – the modelled proc of the second field would be used. If the order of compile changes, i.e. the second entity is moved on the component paint tableau, the module that is used could change. This was not the intended behavior.

In version 10 the process has been made much easier to understand – the external variation always takes precedence. All model definitions are compiled before the external variations are overlaid. This change will mean that the compilation becomes far more predictable with less “magic” and mistakes.

There has been another improvement in compilation of local procs – they are now overlaid. Prior to version 10 you could have, in the model, many entries defined in a single trigger, and if you wished to make a change to just one of them in the component, you would have to break inheritance to them all. Effectively, you would duplicate your code into each component where this was the case. Although it is possible to simulate the inheritance using included procs, it can take quite a bit of planning to implement. With version 10 you are now able to overlay just a single proc module, leaving the inheritance for all others.

So how does this look in the component editor of version 10? The first thing you will see is that only the external variation code is displayed, not the modelled code. To enable easy navigation to all the code compiled into the component, a Compiled Module Information (CMI) panel has been added to the editor. It shows all modules compiled into the component. Double clicking on a module in the CMI causes a navigation action and you will be taken to to the definition of the code module – opening a new editor (entity, included proc, etc.) if required. This is a big time saver for the developer.