Internationalization in VB.Net : Choosing the right structure type - vb.net

I'm about to start translating my vb.net application, and I don't want to use the default methods provided by Visual Studio to do so. I need my application to be very light, and it nearly doubles it size to use the resources option.
Therefore, I'm planning to use some thing like a class, of which I would have one instance per language. Since I don't want to distribute language files as separate files (I'd rather have them hard-coded), I would like to find an easy way to check if every field of the class is initialized. I was thinking of something like an Interface, where I would do something like this:
Public Interface Language
Dim HelloMsg As String
Dim GoodbyeMsg As String
End Interface
Public class English Implements Language
HelloMsg = "Hello!"
GoodbyeMsg = "Goodbye!"
End Class
It's obviously not the right way to do it (although I could use properties instead of vars), but I was wondering whether the was a way to have the compiler check that everything is translated and warn about it if not.
Anyway, maybe is there a much better way to handle this problem ?
Thanks a lot!
CFP.

I'm not convinced that you should dump the resource-based localization approach just because your app has grown in size. Indeed, it could've grown from 100 Kb to 200 Kb, but this is it! It won't grow this much more. And 200 Kb is nothing nowadays.
So my advice is to reconsider and go resource-based route.

I've decided to use a singleton class that loads a translation file, with a method that loops through all items on a form and translate on-the-fly. See Create Synchronicity source code for more details (more specifically TranslateControl in this code file)

Related

Enforcing API boundaries at the Module (Distribution?) level

How do I structure Raku code so that certain symbols are public within the the library I am writing, but not public to users of the library? (I'm saying "library" to avoid the terms "distribution" and "module", which the docs sometimes use in overlapping ways. But if there's a more precise term that I should be using, please let me know.)
I understand how to control privacy within a single file. For example, I might have a file Foo.rakumod with the following contents:
unit module Foo;
sub private($priv) { #`[do internal stuff] }
our sub public($input) is export { #`[ code that calls &private ] }
With this setup, &public is part of my library's public API, but &private isn't – I can call it within Foo, but my users cannot.
How do I maintain this separation if &private gets large enough that I want to split it off into its own file? If I move &private into Bar.rakumod, then I will need to give it our (i.e., package) scope and export it from the Bar module in order to be able to use it from Foo. But doing so in the same way I exported &public from Foo would result in users of my library being able to use Foo and call &private – exactly the outcome I am trying to avoid. How do maintain &private's privacy?
(I looked into enforcing privacy by listing Foo as a module that my distribution provides in my META6.json file. But from the documentation, my understanding is that provides controls what modules package managers like zef install by default but do not actually control the privacy of the code. Is that correct?)
[EDIT: The first few responses I've gotten make me wonder whether I am running into something of an XY problem. I thought I was asking about something in the "easy things should be easy" category. I'm coming at the issue of enforcing API boundaries from a Rust background, where the common practice is to make modules public within a crate (or just to their parent module) – so that was the X I asked about. But if there's a better/different way to enforce API boundaries in Raku, I'd also be interested in that solution (since that's the Y I really care about)]
I will need to give it our (i.e., package) scope and export it from the Bar module
The first step is not necessary. The export mechanism works just as well on lexically scoped subs too, and means they are only available to modules that import them. Since there is no implicit re-export, the module user would have to explicitly use the module containing the implementation details to have them in reach. (As an aside, personally, I pretty much never use our scope for subs in my modules, and rely entirely on exporting. However, I see why one might decide to make them available under a fully qualified name too.)
It's also possible to use export tags for the internal things (is export(:INTERNAL), and then use My::Module::Internals :INTERNAL) to provide an even stronger hint to the module user that they're voiding the warranty. At the end of the day, no matter what the language offers, somebody sufficiently determined to re-use internals will find a way (even if it's copy-paste from your module). Raku is, generally, designed with more of a focus on making it easy for folks to do the right thing than to make it impossible to "wrong" things if they really want to, because sometimes that wrong thing is still less wrong than the alternatives.
Off the bat, there's very little you can't do, as long as you're in control of the meta-object protocol. Anything that's syntactically possible, you could in principle do it using a specific kind of method, or class, declared using that. For instance, you could have a private-class which would be visible only to members of the same namespace (to the level that you would design). There's Metamodel::Trusting which defines, for a particular entity, who it does trust (please bear in mind that this is part of the implementation, not spec, and then subject to change).
A less scalable way would be to use trusts. The new, private modules would need to be classes and issue a trusts X for every class that would access it. That could include classes belonging to the same distribution... or not, that's up to you to decide. It's that Metamodel class above who supplies this trait, so using it directly might give you a greater level of control (with a lower level of programming)
There is no way to enforce this 100%, as others have said. Raku simply provides the user with too much flexibility for you to be able to perfectly hide implementation details externally while still sharing them between files internally.
However, you can get pretty close with a structure like the following:
# in Foo.rakumod
use Bar;
unit module Foo;
sub public($input) is export { #`[ code that calls &private ] }
# In Bar.rakumod
unit module Bar;
sub private($priv) is export is implementation-detail {
unless callframe(1).code.?package.^name eq 'Foo' {
die '&private is a private function. Please use the public API in Foo.' }
#`[do internal stuff]
}
This function will work normally when called from a function declared in the mainline of Foo, but will throw an exception if called from elsewhere. (Of course, the user can catch the exception; if you want to prevent that, you could exit instead – but then a determined user could overwrite the &*EXIT handler! As I said, Raku gives users a lot of flexibility).
Unfortunately, the code above has a runtime cost and is fairly verbose. And, if you want to call &private from more locations, it would get even more verbose. So it is likely better to keep private functions in the same file the majority of the time – but this option exists for when the need arises.

IStringLocalizer vs resource.designer.cs

I don't really like the idea of injecting localizer, what's wrong with the classic approach of having a class with static properties generated? It's much easier to use than injecting IStringLocalizer everywhere I want to localize.
I understand that using this interface allows us to swap the implementation to localize using something other than resources but if we only want to use resources, is it worth the trouble?
Short answer is, ease of use and speedup of development time.
A shared class with static properties requires to pre-define all localized strings in advance.
But in case of using IStringLocalizer you don't have to pre-define the localized strings, you just type plain texts during development, and later on you can define the localized versions in the resource files.
additionally, it will much easier to manage localization with IStringLocalizer if you have a team working on the same project.

How to specify the class and the method to make a MS tweak on it?

How to specify the class and the method to make a MS tweak on it ?
There is a lot of classes and methods in every single app or in springboard :(
Any way to make it easy to find the one I'm gonna work on ?
You need to seek for the stuff you'll use within the dumped headers you have for the app. The names of the classes are usually (at least, in SpringBoard) explicit enough to let you guess their purpose.
Finding the right class/method to hook can be long, but you can use Flex (available on the Cydia Store) to browse headers and methods more easily

Random access files at clean VB.NET way

After working some time in VB.NET I would like to get rid of Microsoft.VisualBasic dependencies.
Since with text files and string manipulation goes easy here I don't know what to do.
Is it possible to write equivalent code in VB.NET without using Microsoft.VisualBasic namespace and how this code should look like?
Dim fnum As Integer = FreeFile()
FileOpen(fnum, "Setup\myadmin", OpenMode.Random, OpenAccess.ReadWrite, OpenShare.Shared, Len(idstruct))
FilePut(fnum, idstruct, 1) 'structure data to file in record 1
FileClose(fnum)
As much as I sympathise with your desire to remove all references to the Microsoft.VisualBasic namespace, and as much as I think that doing so has value, sometimes it's just not worth the trouble. The namespace does contain some useful tools which are not easily reproduced without it.
For instance, the TextFieldParser comes to mind. It allows you to easily read CSV and fixed-width files. There is no other class like it in the .NET framework. So, is it worth it to reinvent the wheel just so that you don't reference the Microsoft.VisualBasic namespace? I would argue that it's not worth it.
While it would be possible to reproduce the behavior of FileGet and FilePut using FileStream and the StreamReader, StreamWriter, BinaryReader, and BinaryWriter classes, it's probably not worth all the trouble. The FileGet and FilePut methods are provided specifically for backwards compatibility, so if compatibility with old systems is your goal, as much as it pains me to say it, using FileGet and FilePut is an appropriate solution.
However, some of this advice hinges on the type of data. If, for instance, the structure only contains fixed width strings, that would be very easy to duplicate with the StreamReader and StreamWriter, or with the TextFieldParser. Or, if it contains just integers, perhaps it will be easy to reproduce with the BinaryReader and BinaryWriter.
However, even if you can easily reproduce the logic using other non-VB-only classes, doing so doesn't gain you anything. In fact, your code will be more complicated and it will be less self-documenting. When you see code using FileGet and FilePut, not only is it easy to tell what is being done, but it is also obvious that it is for backwards compatibility. If you replace them with your own logic, the necessity for backwards compatibility would not be obvious without adding comments to the code.
If you don't like looking at them, which I can certainly understand, it may be worth wrapping them in a wrapper class. For instance, you could create a data-access style class with load/save methods which internally just use FileGet and FilePut. Doing so would be good practice anyway. That way, if you ever choose to store the data in a different format, or a different data source (such as a database), you could change it in the one class without having to rewrite all of your code.
One other thing I've just found is this MSDN page about My.Computer.FileSystem:
http://msdn.microsoft.com/en-us/library/0b485hf7%28v=vs.90%29.aspx
which I found was referred to from the MSDN page on FilePut:
http://msdn.microsoft.com/en-us/library/0s9sa1ab%28v=vs.90%29.aspx
From posts like this one It's my understanding that it's just a wrapper for System.IO anyway, but it supposedly provides a "more convenient and understandable" interface to the underlying IO functions.
If you're referring to your use of the LEN() function (which is the only thing I can see that refers to Microsoft.VisualBasic namespace, unless I'm missing something), then you can just use String.Length instead. E.g. idstruct.Length, assuming idstruct is a String.
Look at System.IO.FileStream. The approach is a bit different, but it is quite simple.
Dim fs As New FileStream(mUserFile, FileMode.XXX, FileAccess.XXX)
or:
Using fs as New FileStream....
End Using
The main thing that will change is that rather than writing a structure, you would convert it to an array of bytes (Count would be the length of your array, offset 0 in your example):
fs.Write(byt(), lOffset, lCount)
You COULD wrap it all up in a class to emulate the old random access file method if there it a lot of legacy code to support. There is also a BinaryReader and BinaryWriter and you could also look into serialization if the data is large but mostly static.

Using LuaInterface with VB.net

I'm trying to wire up Lua to my VB.net game I am making. Now, I've read enough to know that I can wire each function up by itself like seen here:
pLuaVM.RegisterFunction("quit", pPrg.GetType(), pPrgType.GetMethod("quit"))
Now, how would I make it possible for my Lua scripters to instance classes, change properties of those classes, etc.
RegisterFunction just seems sloppy and not enough.
Thanks for any help!
My first piece of advise is to not use LUAInterface; as it isn't cross platform, and to instead use IronPython, which is just as easy to pick up as LUA, and will run on Windows and OSX, depending on how you are writing your game; XNA and OpenTK should work cross platform under mono for the graphics engine.
i found this out myself when experementing with LUA for my own vb.net based game, and eventually decided on iron python.
But assuming you want to stick with LUA; here is something you can try.
Based on the fact that you know:
Any vb.net code written cannot be changed after run time, you can do something like this:
Public Shared Lua as New LuaInterface
Sub Game()
Dim LuaCaller as New LuaAccess
Lua("LuaAccess") = LuaCaller
End Sub
Public Class LuaAccess
Public Sub Grant(NewClass as String, Variable as String)
Select Case NewClass
Case "LuaAccess"
Lua(Variable) = New LuaAccess
End Sub
End Class
Then from Lua:
LuaAccess:Grant("LuaAccess", "MyNewLuaAccess")
You can add a new case for each class you want lua to be able to create an instance of; and use that to create new instances of classes.
if you want it to be able to modify an active class used by the main program, just make the subs, or variables, or both in the class shared
Public Shared MyVar as Integer
That way there is only one copy of the variable, which any part of the application (even Lua) can modify.
Although I'll be honest IronPython really is more suited to this kind of thing, and is still being actively developed, unlike LuaInterface.
remember one thing; when it comes to scripting, you really don't want to give the scripting engine too much control; when it comes to games specifically you're giving them access to everything your engine can do; and that can be used to cheat if you are not careful.
good luck, and i hope i helped.
Based on LuaInterface runtime v2.0.50727
(the one that uses Lua51.dll)