The result of GetParent('c:\1\2\') is 'c:\1\2'.
And the result of GetParent('c:\1\2') is 'c:\1'.
Is this the normal/expected behavior? If yes, what is the logic behind it?
This behaviour might seem a little odd but it is by design. This class is modelled on the .net class Directory. The documentation for Directory.GetParent says:
The string returned by this method consists of all characters in the path up to, but not including, the last DirectorySeparatorChar or AltDirectorySeparatorChar. For example, passing the path "C:\Directory\SubDirectory\test.txt" to GetParent returns "C:\Directory\SubDirectory". Passing "C:\Directory\SubDirectory" returns "C:\Directory". However, passing "C:\Directory\SubDirectory\" returns "C:\Directory\SubDirectory", because the ending directory separator is after "SubDirectory".
Related
I am trying to call a method of a class that I only know by name as a String. Now therefore I would need a ClassMirror of that class that allowes me to instantiate an instance. However, creating ClassMirrors seems to be only possible by entering a type using reflectClass(Type) or by passing an already existing instance of that class into reflect(dynamic). So these aren`t helping if I only have a String.
In Java you can do this pretty easily, by calling Class.forName(String). Then you would get a Constructor instance, make it accessibly and call it.
Does anyone know if this is even possible in dart? What seems weird is that once you have a ClassMirror you can access fields and methods by passing symbols, which can be created by Strings.
You can put a specific list of strings to map to a specific list of closures to create a new object with specific parameters.
But you can't get a reflection without using dart:mirrors, which is being deprecated, and also had a negative impact on tree shaking to get the payload size down.
In general, you're invited to look at the package:reflectable to achieve most of what you'd want out of dart:mirrors, using source-to-source builders.
Given a List, is it possible to test whether the list is growable?
Trying to set the length and catching an UnsupportedError seems like a solution (though it isn't clear what would happen if you just set the length to the same value). Any better solution?
There is no way to detect if a list is growable (short of using reflection to find the implementation type, which is brittle, won't work the same way in dart2js, and increases code size).
The only valid use-case we encountered was to have checks/asserts when a library returns a list. In all other cases a function/library tried to modify an argument without knowing if it was allowed to do that.
If a function/library can work destructively it should require a boolean (or similar) so that the callers can decide if their argument can be changed. The callee should never silently modify its inputs unless it is obvious (for example fillFoo(list)) or an argument tells it so (for instance computeSquares(list, inPlace: true)).
http://dartbug.com/13926 is still open, but I expect it to be closed tomorrow with status "NotPlanned".
It is possible using reflection (not straight-forward either).
I guess this isn't any better than catching the exception.
print(MirrorSystem.getName(reflect(new List.from([0,1,2], growable: true))
.type.simpleName) == ('_GrowableList'));
EDIT
It is discouraged to use the name of a symbol - see Converting a Symbol into a String
I've found properties corresponding to each action named like this: MVC.<Controller>.<Action>Params, they contain parameter names for each action. What are they for and how they can be used?
There were some edge scenarios where it was interesting to pass the parameter name as a constant. I can't instantly recall what that person was doing, but I could see this being useful is calls to AddRouteValue. In the end, it's all about never to have to use a literal string that refers to a C# object, whether it's a class, method, or param.
I am currently writing some methods to determine certain paths on the hard drive. For the sake of the example, let's call them GetBasePath(), GetSpecialPath(), etc.
My question is, from a design point of view, how should these methods behave if the directories do not exist in the expected location? I am a bit puzzled what the best practice might be in this case.
Some contradicting possible solutions that I considered:
1: The name of the method should tell you what it does, therefore GetBasePath or GetSpecialPath do not imply that the method checks for existence. It's the caller's business to check for existence himself. Also, a method called GetBasePathIfItExists would be a bit over the top...
2: If the paths do not exist, that is an exceptional case, because they are expected to exist (at least in my case), therefore the methods should throw exceptions.
3: The methods should only return VALID paths, therefore if it cannot return a valid existing path, an empty string should be returned. (E.g.: Microsoft does this for Environment.GetFolderPath())
I am currently favoring solution 1, as this has the advantage that you can easily tell the user WHERE the path is expected to exist. An exception could tell you the same, but is it really an exceptional case?
What would you suggest?
I hope this question is not too specific and other readers can benifit from a good answer as well.
If these paths are expected to always exist, then their non existence is exceptional and you should indeed throw an exception. This is also how the framework operates in many of the IO namespace classes.
If there is a reasonable expectation that these paths may not exist, you may want to provide an xxxExists boolean method that will check for existence and allow the programmer to do something about the issue.
Another option might be to have the functions create the corresponding directory if it doesn't already exist. Of course the ability to do this depends on the expected permissions of the calling application and the directory location. If the directory can't be created (for example, if a file of the same name already exists there), then throw an exception.
I noticed that the MapRoute extension includes an overload that accepts a string[] parameter which is called 'namespaces'. I read what Google had for me on it, and supposedly this is to help the framework find controllers in places it wouldn't otherwise look.
I did some spiking, and tried putting controllers in weird locations. I put one in the Scripts folder; I even built one in a separate assembly with a separate root namespace.
Without putting anyting in the namespaces param, everything worked fine. If I put just one of the namespaces in the namespaces param, it still found all my controllers. I thought maybe it would use that array to disambiguate between similarly named controllers, but that didn't happen either. A HomeController in MyProj.Controllers and one in SomeOtherName.Stuff would collide still.
So my question is, is that parameter deprecated? Or is it still used somehow in a way that I have yet to discern?
Ok, so after further testing, I figured out that it is not a filter, exactly, but it kinda is also. I gave you 'answer' credit even though you're partially wrong.
So, it does, after all, act like I thought it should which is to say it disambiguates. Basically, the logical flow is something like this:
Look for a namespace in the _cache that matches one in the namespaces array
if that's found, look for a controller of the right name
-- if that's found, return it
-- if it's not found, return search everywhere else that it'd normally look
if it's not found, search everywhere lese
So, in short, my thought that the namespaces array would serve to disambiguate was correct. The reason my first test in that regard failed is that it only does a perfect match, and I made the mistake of using just the root n/s from the assembly (in other wordss, MyRoot instead of MyRoot.Controllers).
What this namespaces thing allows, then, is to have a HomeController in two different namespaces and match them differently depending on the url or params.
No, the value is not deprecated. It is used in DefaultControllerFactory.cs. Note that if the value is supplied, it completely replaces the standard name spaces searched. When the parameter is not supplied, the name spaces searched our determined by:
HashSet<string> nsDefaults = new HashSet<string>(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);
When the parameter is supplied, the list you supply replaces this value.
In either case, DefaultControllerFactory calls:
GetControllerTypeWithinNamespaces(controllerName, nsDefaults);
...with the list, either the one you supplied, or the default. So it is clear that the value is supported.
When you look at the source code there, and in ControllerTypeCache, you can see the real purpose of the namespaces value: It does not cause the controller factory to look in places that would not otherwise look; rather it is a filter. In other words, it prevents the default controller factory from looking and name spaces that it would otherwise search for controllers.