Showing posts with label magik. Show all posts
Showing posts with label magik. Show all posts

Friday, August 23, 2013

Insert coordinates from text file into Smallworld database

I recently received a query from a reader asking if I could show him how to insert coordinates from a text file into Smallworld database.  I have put together a gist that shows how to do this.  I started off by using a LWT approach but then remembered that the recommended approach is to use the record transaction APIs.  So the gist includes both styles of database writing.


Monday, October 10, 2011

Exporting Smallworld Data to KML

There was a recent question on the sw-gis Yahoo group asking about how to export a Smallworld trail to KML for use in other applications. It turns out that can be done easily using the open source Magik Components Library (mclib). The following video demonstrates how this is done. Important information:
- Magik Components Library link is here
- Thanks to Brad Sileo (iFactor Consulting) for contributing this code to the MCLIB project.



Give it a try and let me know what kind of cool export applications you are using. And if you have any improvements to make to the functionality, please feel free to contribute to MCLIB.

Thursday, August 18, 2011

Smallworld Magik JSON Parser

I added a Magik JSON Parser to the Magik Components Library today.

Here is a demo of how it works...


Tuesday, July 12, 2011

Emacs Magik Debugger key binding

My latest favorite tool in Magik is the Magik Debugger. The Magik Debugger has been around for quite some time, but it was always inconvenient to load it. Starting at 4.1, the Emacs that ships with SW has a key binding (F4-d) that automagikally launches the Magik Debugger for the method in which your cursor is active. It makes it very easy to launch and using the debugger can often be quicker to use than scattering debug write/show statements throughout your code.

Igor has a nice demo video of this feature here.

Monday, June 20, 2011

Hiding behind #debug

I saw code like this today...

_for a_key,a_pred _over preds.fast_keys_and_elements()
_loop
#debug write(a_key, ": ", a_pred)
_endloop


... clearly the developer had wanted to only have the output write while in #debug mode. That seems like a good idea to me. But what would make the code even more efficient is to put the entire _loop structure behind a #debug tag like this...

#debug _for a_key,a_pred _over preds.fast_keys_and_elements()
#debug _loop
#debug write(a_key, ": ", a_pred)
#debug _endloop


... that way you don't have to worry about the expense of running an iterator at all when not in debug mode.

Tuesday, March 15, 2011

How to write a delimited list in Magik

Over the years I have seen lots of approaches to writing a delimited string. They usually involved creating a loop, writing a delimiter after each element in the collection and then finally removing the last delimiter that was added in the loop.

For example, if you have a list of voltages and you want to concatenate them all in a string that is delimited with a comma and a space ", " you could write something like this...

voltage_string << "  "
_for i_volt _over voltages.fast_elements()
_loop
voltage_string +<< i_volt+", "
_finally
voltage_string << voltage_string.subseq(1,voltage_string.size-2)+"."
_endloop


... or you could use the core write_string_with_separator() procedure and write equivalent code like this...

voltage_string << write("  ",
write_string_with_separator(voltages,", "),
".")


I like the latter approach because it is more concise and it very clearly indicates what you are trying to do... write a string with delimiter.

A call for identifying your custom changes

Reviewing code changes is difficult at best, but when reviewing a "basic_change" in Magik, it would be very helpful if the changes were very clearly bracketed with private comments.

For example, you might have an #EMQ like this...

_method some_class.some_method()
## some_method() : some_return_value
##
## does something crazy

_global a

(a.b[c], a.b[d]) << (a.b[d], a.b[c])
_endmethod
$


... which you might want to refactor to be more robust. It would be really, really helpful to future code reviewers if you very explicitly indicated which lines of code you changed. Like this...

_method some_class.some_method()
## some_method() : some_return_value
##
## does something crazy

_global a

# BEGIN CHANGES
#(a.b[c], a.b[d]) << (a.b[d], a.b[c])
_try _with cond
(a.b[c], a.b[d]) << (a.b[d], a.b[c])
_when error
write("!!! EMQ !!!",cond.report_string)
_endtry
# END CHANGES
_endmethod
$


You can see that I actually commented out the original line and then put a copy of the line back in the _try block. This makes it very easy for a reviewer (and text diff tools) to see what has changed. I would not recommend using this approach for your own product code. Source Code control systems can identify these changes for you. What I am more concerned about is cases where you have redefined a core Smallworld method to address some business requirement. Once compiled into the image, it is very difficult to find the original version of the method, so the more that you can document as a customizer, the better it will be for future code readers.

Igor over at MagikEmacs pointed out to me that Alt-c in his extended version of Emacs does exactly this "changed code block" highlighting for you. You can see an example in his Screen-cast #3 at 3:50 where he uses exactly this technique.

Dialog Designer now has a forum

Graham's excellent Dialog Designer now has an online forum. You can join here.

If you are not familiar with Dialog Designer, you should try it out. It is a very slick tool that lets you build GUIs in Magik with a drag-and-drop interface. All the difficult GUI generation code is stubbed out for you and you can focus on building the engine/database behavior.

You can read sworldwatch blog posts about Dialog Designer here.

And it is open-sourced by iFactor Consulting so you have free access to the product! You can read more on the product page here.

Monday, March 14, 2011

How not to define a symbol in Magik

Found in some custom code...

tbl_name << "tx_query".as_symbol()

... should really be...

tbl_name << :tx_query

If you are calling :as_symbol() on a string, that should be a red flag to you that you are doing something wrong. You should really only call :as_symbol() on a variable.

Friday, March 11, 2011

How to find the Magik source file for an exemplar definition

Many of you are likely aware of the object.method(method_name).source_file pattern that you can use to determine the file in which the method definition is contained. But did you know that you could also use the same pattern to find the file location for the actual object exemplar?

For example, in my Web Maps Connector image, I want to figure out where map_view.int!do_render() is actually defined. I can do the following to get that information.

MagikSF> map_view.method(:int!do_render|()|).source_file
$
"C:\ifactor\products\workspace\Virtual_Earth_Connector\trunk\source\patches_z_proposed\p1000001_1_if_vec_map_plugin.magik"

But what if I want to determine how that patch of map_view.int!do_render() has modified the original version of that method? Where can I find that original method definition? While it is not 100% guaranteed, Magik style conventions strongly suggest that object method definitions be kept in the same file as the object's exemplar definition. Great. So all we need to do is find the file in which the def_slotted_exemplar(:map_view) is called. Here is how you do that...

MagikSF> map_view.method(:exemplar).source_file
$
"C:/Smallworld41/product/modules/sw_swaf/map_plugin/source/map_view.magik"


The trick is to request the source file for the special method called :exemplar. Happy debugging!

Monday, March 7, 2011

Evil Magik Question

If you can get your mind around this question on Twitter, let me know. Or better yet, reply to the tweet with your answer and hashtag #swgis.


Thursday, March 3, 2011

converting number units in Magik

I was looking at some 3rd party custom code today and noticed what seemed like really helpful methods...
simple_number_mixin.cm_per_foot
simple_number_mixin.cm_to_feet

I think the 3rd party product developers thought this would be a very convenient method. It definitely is, but the problem is that other product developers working on other components made use of these methods. When the 3rd party product was removed, the other custom components broke. The 3rd party product developers rightly declared these methods as RESTRICTED, so the custom product developers should not have called these methods... but we all know that method classifications are widely ignored.

So, how can you make use core Magik classes to do exactly the same thing? Make use of the class unit_value.

Where the custom code might look like...

53.5.cm_to_feet

... you can do exactly the same thing with supported core functionality...

unit_value.new(53.5,:cm).value_in(:feet)


In the same way that each Magik reference to coordinate should really have a corresponding coordinate_system (another pet peeve of mine), most numbers in Magik should ideally be represented as unit_value objects in order to avoid these customized unit conversion methods.

Monday, January 17, 2011

More Emacs Videos

Igor at http://www.magikemacs.com just posted two new videos

MagikEmacs Screen-cast 5
  • shows how to inspect Magik objects using Emacs' Deep Print buffer.
MagikEmacs Screen-cast 6
  • shows how to inspect Magik objects using a combination of Emacs and the core Development Tools application.
  • This is very cool. Provides an easy way to explore Magik objects in an easy-to-navigate Magik GUI.
  • Launch the Magik Debugger tool from an Emacs Magik code buffer using F4-D. Very cool!

Saturday, January 8, 2011

Running Magik Remotely from Google Talk

Bhimesh over at the Magik Fun blog has posted a video of how he uses the XMPP protocol to send/retrieve standard input/output from Magik. It kind of reminds me of the remote_cli class in Magik.

You can view the blog post here.

Thursday, January 6, 2011

Exporting Node Coordinates via FME

I received a query today from a reader that wants to export the node coordinates for each electric conductor sent to FME. The sw_gis!node table is not a user table in Smallworld and is therefore not typically exposed to the FME plugin. But if you use the GE FME plugin, you can make use of the pseudo_fields functionality to gather up the relevant node information and send it to FME as a conductor attribute.

The basic steps are:
  1. define pseudo_fields on the conductor class (or whatever class you are interested in)
  2. write Magik support code that populates the pseudo_fields with appropriate node-based coordinates.
  3. create a FME Workspace that reads the new pseudo_fields and processes the appropriately.

This video describes these steps in more detail.


Wednesday, November 17, 2010

Visualization in Smallworld (Part 2)

Back in January, I posted an article about Visualization in Smallworld. The article was long on words and short on visuals, so now I have created a video that shows more clearly what the post about.

Tuesday, November 2, 2010

Not happy with Magik in Emacs? See the MDT Webinar.

I've written a few posts related to Astec's MDT Eclipse plugin over the years. I have gotten used to using Emacs but I realize that is not for everyone (especially people coming to Magik from other development environments). So I was happy to read that Astec would be hosting a MDT webinar at the beginning of December. The timing of it is aimed at participants in the western hemisphere.

(Maybe Astec can set up a YouTube channel with additional demo videos for those who cannot attend the webinar).

Here's the announcement...

We would like to invite all Magik developers to an online live demo presentation of MDT (Magik Development Tools): the new and modern IDE for Magik.


Session is planned to be held on December, the 2nd, 1 p.m. Washington D.C. time.

MDT live demo presents main MDT features from simple basics to most advanced stuff. Topics included in this demo are as follows:
- creating project, runtime, session;
- importing and exporting (preferences, sessions, products etc.);
- working with code;
- browsing through code;
- managing project dependencies;
- search;
- version control systems;
- debugging

duration: approx. 60 min.

Due to limited number of seats please confirm your interest on mdt@astec.net. If needed, we will hold another session 90 minutes after the first one. Joining details and link will be posted one week prior to the presentation.

Cheers,
MDT Team

Friday, October 15, 2010

Decimal Degrees vs DMS

I had someone ask me today how to configure Smallworld to show Decimal Degrees or Degrees/Minutes/Seconds.

I found two ways. The one way is to use the Administration application's Unit Display Groups tool to change the "Sub Units?" value



The other option is to create some Magik code in your image build process that changes the sub units setting.

E.g.
_block
unit_manager.unit(:degree).default_format.use_sub_units? << _false # (or _true)
_endblock
$

Wednesday, August 25, 2010

Where was that method or exemplar defined?

Do you ever want to know the source file for a particular method? You can use the class browser to jump to the code or you can do this...

MagikSF> circle.method(:new|()|).source_file
$

Most of the time, jumping to a method is faster in the Class Browser than using this code snippet.

But what if you want to jump to the file where the actual class exemplar (not the method) is defined? Then you can do this...

MagikSF> circle.method(:exemplar).source_file
$

I know of no way to do this latter action from the Class Browser.

Wednesday, March 31, 2010

Getting a resource file from a module

I am looking at some product upgrade code that is trying to find a resource file relative to a module definition and I thought this would be a good example of how not to do it.

The existing code is...

_for a_file _over sw_module_manager.module(_self.module_name).resource_files(:data, _true).fast_elements()
_loop
_if a_file.index_of_seq(xml_file_name) _isnt _unset
_then
fn << a_file
_leave
_endif
_endloop


... and can be replaced with ...


fn << smallworld_product.get_data_file(xml_file_name,office_upgrade_runner.module_name)

Not only is the latter easier to read than the former, the former does not actually return the expected files.[Note: I spoke too soon. The former code does work but in my opinion is not as clean.] Additionally, the former bit of code calls :resource_files() which is a restricted method. The latter code calls :get_data_file() which is classified as advanced and may legitimately be called from other methods.