I have an array of objects in MATLAB and I've called their constructors in a loop:
antsNumber = 5;
for counter = 1: antsNumber
ant(counter) = TAnt(source, target);
end
MATLAB warns me to use preallocation to speed up the process. I do know the benefits of preallocation but I don't know how to do that for objects.
Here are a few options, which require that you design the class constructor for TAnt so that it is able to handle a no input argument case:
You can create a default TAnt object (by calling the constructor with no input arguments) and replicate it with REPMAT to initialize your array before entering your for loop:
ant = repmat(TAnt(),1,5); %# Replicate the default object
Then, you can loop over the array, overwriting each default object with a new one.
If your TAnt objects are all being initialized with the same data, and they are not derived from the handle class, you can create 1 object and use REPMAT to copy it:
ant = repmat(TAnt(source,target),1,5); %# Replicate the object
This will allow you to avoid looping altogether.
If TAnt is derived from the handle class, the first option above should work fine but the second option wouldn't because it would give you 5 copies of the handle for the same object as opposed to 5 handles for distinct objects.
The following link might be of help:
http://www.mathworks.com/help/techdoc/matlab_oop/brd4btr.html#brd4nrh
Web archive of dead link
New link:
http://de.mathworks.com/help/matlab/matlab_oop/creating-object-arrays.html
The warning it gives is superfluous, unless you are doing computational heavy stuff, I would ignore it.
The reason why it's giving you the error, is because it has to find new space. Say, I give you a list of seven objects, and I tell you that you need to place them all in a row, I then go off, and give you a few more things you need to put somewhere. I then give you an eighth object and tell you to put it right after the seventh. Because you have stuff where the eighth object is, you either have to move it out of the way, or you have to move all seven objects. Matlab, is telling you it would be faster if you were to tell it beforehand that you want to put 5 things in there, rather than just giving it things one by one, having to look for a new spot each time. You can do that by adding this line to the top of your code:
ant = [1:5];
There are also other ways to do this too.
Not sure if I got your problem right, but if you want to initialize an array of your self-defined class "TAnt", here is how I would do it
For TAnt's constructor method, put something like:
function obj = TAnt(source, target)
if nargin > 0
obj.mySource = source;
obj.myTarget = target;
else
obj.mySource = defaultValue;
obj.myTarget = defaultValue;
end
end
Then to initialize/pre allocate an array of default TAnt objects,
ants(1,n) = TAnt(); % n is the length of your ants array
Related
There is an API provided function, let's call it createBase which returns a table (object). I want to add methods to this table, but I can't just do x = createBase() and then function x:foo() because I have another function similar to createBase, but it's createExtended. It might be easier to explain with the code I have so far:
import api --I don't know how you'd do this in vanilla Lua, I'd use os.loadAPI("api") but that's computercraft specific, I think
Extended = {}
function Extended:foo()
print("foo from extended")
end
function createExtended(params)
x = api.createBase(params)
Extended.__index = x
return Extended --this is obviously wrong: you can't return a class and expect it to be an object
end
Of course, this doesn't work: but I don't know how I might make it work either. Let's assume the table returned by createBase has a function called bar which just prints bar from base. With this test code, the following outputs are given:
e = createExtended()
e.foo() --prints "foo from extended"
e.bar() --nil, therefor error
How can I make this possible, short of defining function x.bar() inside createExtended?
Thanks in advance.
The very simplest way is to attach the method to it directly, instead of using a metatable.
local function extend(super_instance)
super_instance.newMethod = newMethod
return super_instance
end
local function createExtended(...)
return extend(createSuper(...))
end
This will work, unless your superclass uses __newindex (for example, preventing you from writing to unknown properties/methods), or iterates over the keys using pairs or next, since it will now have an additional key.
If for some reason you cannot modify the object, you will instead have to 'wrap' it up.
You could make a new instance which "proxies" all of its methods, properties, and operators to another instance, except that it adds additional fields and methods.
local function extend(super_instance)
local extended_instance = {newMethod = newMethod}
-- and also `__add`, `__mul`, etc as needed
return setmetatable(extended_instance, {__index = super_instance, __newindex = super_instance})
end
local function createExtended(...)
return extend(createSuper(...))
end
This will work for simple classes, but won't work for all uses:
Table iteration like pairs and next won't find the keys from the original table, since they're not actually there. If the superclass inspects the metatable of the object it is given (or if the superclass is actually a userdata), it will also not work, since you'll find the extension metatable instead.
However, many pure-Lua classes will not do those things, so this is still a fairly simple approach that will probably work for you.
You could also do something similar to Go; instead of having a way to 'extend' a class, you simply embed that class as a field and offer convenience to directly calling methods on the wrapping class that just call the methods on the 'extended' class.
This is slightly complicated by how 'methods' work in Lua. You can't tell if a property is a function-that-is-a-property or if it's actually a method. The code below assumes that all of the properties with type(v) == "function" are actually methods, which will usually be true, but may not actually be for your specific case.
In the worst case, you could just manually maintain the list of methods/properties you want to 'proxy', but depending on how many classes you need to proxy and how many properties they have, that could become unwieldy.
local function extend(super_instance)
return setmetatable({
newMethod = newMethod, -- also could be provided via a more complicated __index
}, {
__index = function(self, k)
-- Proxy everything but `newMethod` to `super_instance`.
local super_field = super_instance[k]
if type(super_field) == "function" then
-- Assume the access is for getting a method, since it's a function.
return function(self2, ...)
assert(self == self2) -- assume it's being called like a method
return super_field(super_instance, ...)
end
end
return super_field
end,
-- similar __newindex and __add, etc. if necessary
})
end
local function createExtended(...)
return extend(createSuper(...))
end
I just found out that like C#, VB.NET also has the using keyword.
Until now I thought it didn't have it (stupid of me, I know...) and did stuff like this instead:
With New OleDbConnection(MyConnectionString)
' Do stuff
End With
What are the implications of this compared to doing it with a using statement like this
Using cn as New OleDBConnection(MyConnectionString)
With cn
' Do stuff with cn
End With
End using
UPDATE:
I should add that I am familiar with what the using statement does in that it disposes of the object when the construct is exited.
However, as far as I understand the With New ... construct will have the object mark the object as ready for garbage collection when it goes out of scope.
So my question really is, is the only difference the fact that with using I will release the memory right away, whereas with the With construct it will be released whenever the GC feels like it? Or am I missing something bigger here?
Are there any best practice implications? Should I go and rewrite all the code with I used With New MyDisposableObject() ... End With as Using o as New MyDisposableObject()?
With Statements/Blocks
However, as far as I understand the With New ... construct will have the object mark the object as ready for garbage collection when it goes out of scope.
This is both true and not true. It is true in the sense that all objects are "marked" (purists might quibble with this terminology, but the details are not relevant) as ready for garbage collection when they go out of scope. But then in that sense, it is also not entirely true, as there's nothing special about the With keyword with respect to this behavior. When an object goes out of scope, it is eligible for garbage collection. Period. That's true for method-level scope and it's true for block-level scope (e.g., With, For, Using, etc.).
But that's not why you use With. The reason is that it allows you to set multiple properties in sequence on a deeply-nested object. In other words, assume you have an object on which you want to set a bunch of properties, and you access it this way: MyClass.MemberClass.AnotherMemberClass.Items(0). See all those dots? It can (theoretically) become inefficient to write code that has to work through that series of dots over and over to access the exact same object each time you set a property on it. If you know anything about C or C++ (or any other language that has pointers), you can think of each of those dots as implying a pointer dereference. The With statement basically goes through all of that indirection only once, storing the resulting object in a temporary variable, and allowing you to set properties directly on that object stored in the temporary variable.
Perhaps some code would help make things clearer. Whenever you see a dot, think might be slow!
Assume that you start out with the following code, retrieving object 1 from a deeply-nested Items collection and setting multiple properties on it. See how many times we have to retrieve the object, even though it's exactly the same object every time?
MyClass.MemberClass.AnotherMemberClass.Items(0).Color = Blue
MyClass.MemberClass.AnotherMemberClass.Items(0).Width = 10
MyClass.MemberClass.AnotherMemberClass.Items(0).Height = 5
MyClass.MemberClass.AnotherMemberClass.Items(0).Shape = Circle
MyClass.MemberClass.AnotherMemberClass.Items(0).Texture = Shiny
MyClass.MemberClass.AnotherMemberClass.Items(0).Volume = Loud
Now we modify that code to use a With block:
With MyClass.MemberClass.AnotherMemberClass.Items(0)
.Color = Blue
.Width = 10
.Height = 5
.Shape = Circle
.Texture = Shiny
.Volume = Loud
End With
The effect here, however, is identical to the following code:
Dim tempObj As MyObject = MyClass.MemberClass.AnotherMemberClass.Items(0)
tempObj.Color = Blue
tempObj.Width = 10
tempObj.Height = 5
tempObj.Shape = Circle
tempObj.Texture = Shiny
tempObj.Volume = Loud
Granted, you don't introduce a new scope, so tempObj won't go out of scope (and therefore be eligible for garbage collection) until the higher level scope ends, but that's hardly ever a relevant concern. The performance gain (if any) attaches to both of the latter two code snippets.
The real win of using With blocks nowadays is not performance, but readability. For more thoughts on With, possible performance improvements, stylistic suggestions, and so on, see the answers to this question.
With New?
Adding the New keyword to a With statement has exactly the same effect that we just discussed (creating a local temporary variable to hold the object), except that it's almost an entirely pointless one. If you need to create an object with New, you might as well declare a variable to hold it. You're probably going to need to do something with that object later, like pass it to another method, and you can't do that in a With block.
It seems that the only purpose of With New is that it allows you to avoid an explicit variable declaration, instead causing the compiler to do it implicitly. Call me crazy, but I see no advantage in this.
In fact, I can say that I have honestly never seen any actual code that uses this syntax. The only thing I can find on Google is nonsense like this (and Call is a much better alternative there anyway).
Using Statements/Blocks
Unlike With, Using is incredibly useful and should appear frequently in typical VB.NET code. However, it is very limited in its applicability: it works only with objects whose type implements the IDisposable interface pattern. You can tell this by checking to see whether the object has a Dispose method that you're supposed to call whenever you're finished with it in order to release any unmanaged resources.
That is, by the way, a rule you should always follow when an object has a Dispose method: you should always call it whenever you're finished using the object. If you don't, it's not necessarily the end of the world—the garbage collector might save your bacon—but it's part of the documented contract and always good practice on your part to call Dispose for each object that provides it.
If you try to wrap the creation of an object that doesn't implement IDisposable in a Using block, the compiler will bark at you and generate an error. It doesn't make sense for any other types because its function is essentially equivalent to a Try/Finally block:
Try
' [1: Create/acquire the object]
Dim g As Graphics = myForm.CreateGraphics()
' [2: Use the object]
g.DrawLine(Pens.Blue, 10, 10, 100, 100)
' ... etc.
End Try
Finally
' [3: Ensure that the object gets disposed, no matter what!]
g.Dispose()
End Finally
But that's ugly and becomes rather unwieldy when you start nesting (like if we'd created a Pen object that needed to be disposed as well). Instead, we use Using, which has the same effect:
' [1: Create/acquire the object]
Using g As Graphics = myForm.CreateGraphics()
' [2: Use the object]
g.DrawLine(Pens.Blue, 10, 10, 100, 100)
' ...etc.
End Using ' [3: Ensure that the object gets disposed, no matter what!]
The Using statement works both with objects you are first acquiring (using the New keyword or by calling a method like CreateGraphics), and with objects that you have already created. In both cases, it ensures that the Dispose method gets called, even if an exception gets thrown somewhere inside of the block, which ensures that the object's unmanaged resources get correctly disposed.
It scares me a little bit that you have written code in VB.NET without knowing about the Using statement. You don't use it for the creation of all objects, but it is very important when you're dealing with objects that implement IDisposable. You definitely should go back and re-check your code to ensure that you're using it where appropriate!
By using With...End With, you can perform a series of statements on a specified object without specifying the name of the object multiple times.
A Using block behaves like a Try...Finally construction in which the Try block uses the resources and the Finally block disposes of them.
Managed resources are disposed by the garbage collector without any extra coding on your part.
You do not need Using or With statements.
Sometimes your code requires unmanaged resources. You are responsible for their disposal. A Using block guarantees that the Dispose method on the object is called when your code is finished with them.
The difference is the Using With...End End
Using cn as New OleDBConnection(MyConnectionString)
With cn
' Do stuff with cn
End With
End using
Calls cn.Dispose() automatically when going out of scope (End Using). But in the With New...End
With New OleDbConnection(MyConnectionString)
' Do stuff
End With
.Dispose() is not explicitly called.
Also with the named object, you can create watches and ?cn in the immediate window. With the unnamed object, you cannot.
Using connection... End Using : Be careful !!!
This statement will close your database connection !
In the middle of a module or form(s), i.e.adding or updating records, this will close the connection. When you try to do another operation in that module you will receive a database error. For connections, I no longer use it. You can use the Try... End Try wihthouth the Using statement.
I open the connection upon entry to the module and close it it upon exit. That solves the problem.
In a MATLAB class I am writing, if the constructor is given 0 arguments, the user is asked to provide a file using uigetfile. If the user cancels the prompt, uigetfile returns 0. In that case it makes no sense to make the object. Is there some way of cancelling the object construction without throwing an exception? If I do an early return I get a malformed object that cannot be used. Here is what the code looks like:
classdef MyClass
methods
function self = MyClass(filename)
if nargin == 0
filename = uigetfile;
if filename == 0
%cancel construction here
return; %I still get a MyClass object with self.filename == []
end
end
self.filename = filename;
end
end
properties
filename;
end
end
However I am unsure if using uigetfile in the constructor is the right thing to do. Maybe it should be the resposibility of another part of my code.
In modern Matlab objects, I don't think it's possible to get out of the constructor without either returning a constructed object or throwing an error. (In the old style classes, the constructor was actually allowed to return whatever it wanted, including objects or primitives of other types, and oh man could that turn in to a mess.) When a constructor is called, the output argument is already intialized with an object with the default property values, so when you call return there, it just skips the rest of initialization and returns the object. If you try to replace out with something besides a MyClass object, that's an error.
Just reorganize the control flow to pull the GUI code out of the constructor, like you're speculating on at the end. Mixing it in to the constructor, especially conditionally, can cause problems. In particular, Matlab expects the zero-arg constructor to always return a scalar object with some sort of default values, because the zero-arg gets called implicitly when filling in elements during array expansion and so on. It's basically used as a prototype.
Lets say I have some "object" that I've defined elsewhere. Maybe it represents a set of items, but is more complex than a simple table. Whatever it may be, it would be logical to iterate over it.
As such, it has a iterator method defined. So I can write this:
local myObject = AbstractObject:new()
for obj in myObject:iterator() do
obj:foo()
end
What I'm wondering is if there is some metamethod trickery that I can do, which will allow me to write this:
local myObject = AbstractObject:new()
for obj in myObject do
obj:foo()
end
So is there?
One slight change to your example would make the semantics a lot less painful:
local myObject = AbstractObject:new()
for obj in myObject() do
obj:foo()
end
That way, you can use a metatable to define the __call metamethod to return myObject:interator(), with code that looks something like this in AbstractObject:new():
setmetatable(newobject, {__call = function() return newobject:iterator() end})
Without the iterator construction, you'll be effectively reusing a single iterator for multiple iterations, which means you'll need to keep the iterator state in the object/creation closure, and reset it after it finishes so the next call will restart the iteration again. If you really want to do this, the best solution would really be to write something for the specific iteration implementation, but this would perform the generic iteration:
local iterator
--table.pack is planned for 5.2
local pack = table.pack or function(...)
local t = {...}
t.n = select('#',...)
return t
end
--in 5.1 unpack isn't in table
local unpack = table.unpack or unpack
function metamethods.__call(...)
if not iterator then
iterator = newobject:iterator()
end
local returns = pack(iterator(...))
if returns[1] == nil then
--iteration is finished: next call will restart iteration
iterator = nil
end
return unpack(returns, 1, returns.n)
end
Again: This should really be adjusted to fit your use case.
The object used after in must be a function, which will be called repeatedly by the generic for loop.
I'm not sure if you can make a table or user object callable like a function, but even then the problem would be that your object can only have one internal iterator state - i.e. it would not allow multiple iterations over the same object (neither concurrently nor sequentially), unless you are somehow explicitly resetting it.
As answered by Stuart, you could use the __call metamethod suitably to return the iterator, but then you would have to write
for obj in myObject() do
obj:foo()
end
This is not quite what we want.
Reading a bit more in PiL, I see that there are more components used in the for loop: the invariant loop state, and the current value of the control variable, which are passed to the iterator function in each call. If we don't provide them in the in expression, they are initialized to nil.
Thus, my idea would be to use these values to distinguish the individual calls.
If you can create a next(element) function for your collection which returns for each element the next one, the implementation would be simple:
metatable.__call = function(_state, _last)
if(_last == nil) then
return obj:first()
else
return obj:next(_last)
end
end
But often we would not have something like this, then it gets more complicated.
I thought about using coroutines here, but these still need a factory method (which we want to avoid).
It would result in something similar like what Stuart wrote (i.e. saving the iterator state somewhere in the object itself or in some other variable related to the object), and using the parameter and/or the iterators result to decide when to create/clean the iterator object/state.
Nothing won here.
Some code to illustrate my question:
With Test.AnObject
.Something = 1337
.AnotherThing = "Hello"
''// why can't I do this to pass the object itself:
Test2.Subroutine(.)
''// ... and is there an equivalent, other than repeating the object in With?
End With
There is no way to refer to the object referenced in the With statement, other than repeating the name of the object itself.
EDIT
If you really want to, you could modify your an object to return a reference to itself
Public Function Self() as TypeOfAnObject
Return Me
End Get
Then you could use the following code
With Test.AnObject
Test2.Subroutine(.Self())
End With
Finally, if you cannot modify the code for an object, you could (but not necessarily should) accomplish the same thing via an extension method. One generic solution is:
' Define in a Module
<Extension()>
Public Function Self(Of T)(target As T) As T
Return target
End Function
called like so:
Test2.Subroutine(.Self())
or
With 1
a = .Self() + 2 ' a now equals 3
End With
I suspect you'll have to repeat yourself. If the expression (to get the object) is expensive, then perhaps drop it into a variable first, and either use that variable in the With, or drop the With completely:
tmp = Test.AnObject;
tmp.Something = 1337;
...
Test2.Subroutine(tmp);
As others have said, you're going to have to write
Test2.Subroutine(Test.AnObject)
This is a good example of why it's worth being a little careful with the With construct in VB.Net. My view is that to make it worth using at all, you really need to be setting more than one or two properties, and/or calling more than one or two methods on the object in the With statement.
When there are lots, and you're not interspersing the .SomeProperty = , or .DoSomething, with other things, it's a terrific aid to readability.
Conversely, a few dots sprinkled amongst a load of other stuff is actually a lot harder to read than not using With at all.
In this case, . characters on their own could easily get lost visually, although of course, it would be syntactically consistent.
I guess they just chose not to implement it. VB isn't really the sort of language where they want to encourage single character language elements, and as a heavy user of VB.Net, I broadly agree with that.
Bottom line: if you're using a With clause with many contained elements, having to refer to the object itself isn't that big a deal. If you're using it with just one or two, maybe better not to use a With clause in the first place.
I'm not sure this is an "answer", per se, but it does illustrate another reason to want a short-hand reference to the parent in a With.
Here's a code sample using a "bare With" (that's what I call it, anyway):
With New frmMySubForm
.lblLinkLabel.Links.Add(New LinkLabel.Link With {.Name = "link", .LinkData = "someUrl", .Start = .lblLinkLabel.Text.IndexOf("link"), .Length = "link".Length})
...
End With
But you actually can't code that because in the term .Start = .lblLinkLabel.Text.IndexOf("link") the compiler expects anything starting with . to be a member of LinkLabel.Link, which .lblLinkLabel isn't.
What would be good, I think, is to be able to write something like:
With New frmMySubForm
.lblLinkLabel.Links.Add(New LinkLabel.Link With {.Name = "link", .LinkData = "someUrl", .Start = Me.lblLinkLabel.Text.IndexOf("link"), .Length = "link".Length})
...
End With
where Me in this scope is taken to be New frmMySubForm.
Yes, I realize that I'm being picky and I could easily assign a variable, etc. But the example form is something I use a lot simply out of preference.