[NTLK] Need help with store parts

Matej Horvat matej.horvat at guest.arnes.si
Tue Mar 1 10:41:41 PST 2022


On Tue, 01 Mar 2022 03:25:14 +0100, NewtonTalk <newtontalk at pda-soft.de>  
wrote:

> // create the soup but don't xmit at build time
> local soup:=theStore:CreateSoupXmit(kSoupName, kSoupIndices, nil);
>
> // add a couple entries
> soup:Add({anInteger: 1}) ;
> soup:Add({anInteger: 2}) ;
>
> This doesn't work because when trying to add the two entries at the end,  
> NTK
> complains
>
>    Undefined variable: Soup
>
> when compiling the package.

Just remove the "local" keyword and it will work.

(You can also use plain old CreateSoup, which doesn't take the third  
parameter; it will make no difference in this case.)

Locals don't work at the top level. I believe this is because  
NewtonScript's scoping rules would otherwise cause all those locals you  
define at compile time to be dragged into any functions you define in text  
files (remember that NewtonScript functions capture the environment they  
are created in - see pages 4-9 to 4-16 of The NewtonScript Programming  
Language).

(Or at least that's the best explanation I can come up with. Another rule  
of NewtonScript is that if a variable can't be found when assigning, a  
local variable is created with that name - and your "soup" variable is  
obviously created somewhere. I guess the rules are different for such  
variables.)

However, I think the easiest (and probably also most space-efficient) way  
to do localization (if you insist on having one package for all languages)  
is to just define a slot (of type "Evaluate") for each language in your  
base view like this:

{
   Greeting: "Hello",
   // add slots for other strings here
}

Then have another slot called Localization (or whatever) set at runtime to  
the language the user chooses, like:

self.Localization := English;  // (assuming the English-language slot is  
called English)

And then you can just use Localization.Greeting to get a string for the  
current language.

The hard part is telling all the child views to use a string which is  
chosen at run time. The obvious way is to call SetValue a bunch of times,  
but that would really bloat your code. The way I'd do it is to have a  
special slot in every view that must be translated and then in the base  
view's (or whatever parent's) viewSetupDoneScript (or elsewhere), call

:ApplyLocalization(self);

which would do something like this (note: I didn't test this):

func(View)
begin
   local LocalizationLabel := View.LocalizationLabel;  // contains a  
symbol, e.g. 'Greeting
   if LocalizationLabel then
     SetValue(View, 'text, Localization.(LocalizationLabel));

   foreach ChildView in View:ChildViewFrames() do
     :ApplyLocalization(ChildView);
end

Of course, not all views have a 'text slot - some might need something  
else...

It's quite a project. Which is probably why neither Apple nor anyone else  
ever bothered with it.


More information about the NewtonTalk mailing list