"""
test with:
cobra -test MyList.cobra
"""
class MyList<of T> implements IEnumerable<of T>
# to-do? implements IList<of T>
"""
Allows for a custom base index and
also has an inclusive range readily available through .maxIndex.
"""
var _items as T[]
var _count = 0
var _capacity = 8
var _minIndex = 1 # fixed for now. always 1
invariant
.minIndex >= 0
(.count == 0) == (.maxIndex < .minIndex)
cue init
base.init
_items = T[](_capacity)
get minIndex from var
get maxIndex as int
ensure result >= 0
return _minIndex + _count - 1
get count from var
pro [index as int] as T
get
require index >= .minIndex and index <= .maxIndex
return _items[index - _minIndex]
set
require index >= .minIndex and index <= .maxIndex
_items[index - _minIndex] = value
def add(item as T)
ensure
this[.maxIndex] == item
.count == old .count + 1
.maxIndex >= .minIndex
body
if _count == _capacity
_capacity <<= 1
newItems = T[](_capacity)
_items.copyTo(newItems, 0)
_items = newItems
_items[_count] = item
_count += 1
def getEnumerator as IEnumerator<of T>
for i in _count, yield _items[i]
def getEnumerator as System.Collections.IEnumerator
implements System.Collections.IEnumerable
return .getEnumerator
def change(changer as ChangeMethod)
"""
Change each element in the list. By using this method you don't even have to loop
through the indexes.
"""
ensure .count == old .count
for i in _count, _items[i] = changer(_items[i]) to T
sig ChangeMethod(item) as dynamic # to-do: put this in MyList and make strongly typed
class TestMyList
test basics
t = MyList<of int>()
assert t.count == 0
assert t.minIndex == 1
assert t.maxIndex == 0
counter = 0
for item in t, counter += 1
assert counter == 0
test add
t = MyList<of int>()
t.add(3)
assert t.count == 1
assert t[1] == 3
expect Exception, assert t[0] == 3
expect Exception, assert t[2] == 3
counter = 0
for x in t
assert x == 3
counter += 1
assert counter == 1
test exceedCapacity
t = MyList<of int>()
for i in 1 : 16+1, t.add(i)
assert t.count == 16
for i in t.minIndex : t.maxIndex+1, assert t[i] == i
test toList
t = MyList<of String>()
t.add('a')
t.add('b')
assert t.toList == ['a', 'b']
test change
t = MyList<of String>()
t.add('a')
t.add('b')
t.change(do(item)=item.toUpper)
assert t.toList == ['A', 'B']
t.change(do(item))
return item.toLower
assert t.toList == ['a', 'b']
Forums
Custom list class
11 posts
• Page 1 of 2 • 1, 2
Custom list class
Stimulated by recent discussion regarding inclusive/exclusive for loops, ranges, etc., I made a custom list class to play around with "going against the grain" with a base index of 1. I also wanted to play with creating a .change method so the elements could be transformed in place without even needing a for loop. Other than that, I haven't used it for anything or fleshed it out completely. Here it is for you to review or play around with if you like:
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
I suppose to make for loops nicer, we could provide a .stopIndex that returns .maxIndex + 1:
Or .indexes:
Or .indices, if you prefer.
for i in 1 : t.stopIndex
print t[i]
Or .indexes:
for i in t.indexes
print t[i]
Or .indices, if you prefer.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
Yeah, forget .stopIndex, .indexes keeps your for loop simple. You don't have to remember to start it with "1 :" and if MyList is generalized to have any .minIndex, it still works:
class MyList...
def indexes as int*
"""
Convienient for numeric for-loops:
for i in t.indexes, print t[i]
Note that if you just need the elements, you can use the common enumerable for loop:
for i in t, print t
And if you need to change each element, you can use .change:
t.change(do(item)=2*item)
"""
for i in .minIndex : .maxIndex + 1, yield i
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
Thanks for taking a stab at this code, Chuck. I'm reading it and trying to come up to speed, so it may be a little time before I respond more fully.
What's the "invariant" keyword for, please? Couldn't find it by Googling "invariant" and ".net", other than discussions of "invariant culture".
Here's a very perplexing (at least to a .Net beginner like me) article about covariance, contravariance and invariance. Is this even related to Cobra's "invariant" keyword? Any links to articles more on point would be appreciated.
http://www.readability.com/articles/plyezesv
What's the "invariant" keyword for, please? Couldn't find it by Googling "invariant" and ".net", other than discussions of "invariant culture".
Here's a very perplexing (at least to a .Net beginner like me) article about covariance, contravariance and invariance. Is this even related to Cobra's "invariant" keyword? Any links to articles more on point would be appreciated.
http://www.readability.com/articles/plyezesv
- DelphiGuy
- Posts: 116
Re: Custom list class
"invariant" comes from Eiffel and is part of Cobra contracts. The invariants of a class are a list of boolean conditions that should always be true upon returning from a method. If a method violates an invariant, an exception will be thrown and you will know that either that method is buggy or the invariant in question is.
You didn't find much for .NET because the concept is not baked into .NET or C# or VB. This is a Cobra add-on.
Other places to search:
-- "cobra invariant" on Google or Bing
-- If you don't get hits with that then try "cobra language FOO"
-- While viewing Cobra discussion forums, use the search box in the upper right hand corner to search discussions.
-- While viewing the Cobra wiki, use the search box in the upper right hand corner to search the wiki.
-- Search the filenames and the source code in Tests\ HowTo\ and Samples\ of a Cobra workspace
You didn't find much for .NET because the concept is not baked into .NET or C# or VB. This is a Cobra add-on.
Other places to search:
-- "cobra invariant" on Google or Bing
-- If you don't get hits with that then try "cobra language FOO"
-- While viewing Cobra discussion forums, use the search box in the upper right hand corner to search discussions.
-- While viewing the Cobra wiki, use the search box in the upper right hand corner to search the wiki.
-- Search the filenames and the source code in Tests\ HowTo\ and Samples\ of a Cobra workspace
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
"invariant" will behave this way pursuant to all instances of every method in the class where the invariant lives?! that's quite amazing and powerful.
- DelphiGuy
- Posts: 116
Re: Custom list class
Yes, it's like an "ensure" for every method in the class.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
From Charles' "Custom list class" post, dated Tue Aug 21, 2012 10:32 pm:
Would someone please remind me why "get" is allowed (as above) independent of a "pro" declaration? Is this a Cobra add-on, or is just plain old .Net? I don't see a discussion of .Net allowing this in either of my .Net books.
I note that "maxIndex" is "get"-ed and declared in the same statement. There's no private version of maxIndex that I see.
Thanks.
- Code: Select all
get minIndex from var
get maxIndex as int
ensure result >= 0
return _minIndex + _count - 1
get count from var
Would someone please remind me why "get" is allowed (as above) independent of a "pro" declaration? Is this a Cobra add-on, or is just plain old .Net? I don't see a discussion of .Net allowing this in either of my .Net books.
I note that "maxIndex" is "get"-ed and declared in the same statement. There's no private version of maxIndex that I see.
Thanks.
- DelphiGuy
- Posts: 116
Re: Custom list class
.NET has properties that can declared in classes, structs and interfaces. They can be get-only, set-only or get+set. This is true in the .NET type system and in the languages C#, VB and Cobra. Then there is the question of syntax:
There is a wiki page on properties. I skimmed it and it looked correct, but possibly incomplete.
You'll note that like other declarations, properties start with a keyword (pro, get, set) followed an identifier.
We could probably come up with some steps like:
1. Decide if you want a get+set, get-only or set-only property.
2. Type the keyword pro, get or set.
3. Type an identifier for the property.
4. Decide if you will implement the property with code or from a variable.
5. If code, type the data type of the property with "as type"
etc.
HTH
# explicit syntax using pro keyword:
class X
var _a as int
pro a as int
get
return _a
set
_a = value
# you will get tired of typing that after awhile
# here is a shortcut:
class X
pro a from var as int
# Cobra won't complain if you declare the var explicitly.
# This was the original shortcut syntax implemented before the above
class X
var _a as int
pro a from var
# get-only properties are somewhat common, at least in my code, because
# I may not want to account in the implementation for certain things being
# changed, and/or it may simply not be necessary.
# Note the use of var initialization below:
class X
get children from var = List<of X>()
There is a wiki page on properties. I skimmed it and it looked correct, but possibly incomplete.
You'll note that like other declarations, properties start with a keyword (pro, get, set) followed an identifier.
We could probably come up with some steps like:
1. Decide if you want a get+set, get-only or set-only property.
2. Type the keyword pro, get or set.
3. Type an identifier for the property.
4. Decide if you will implement the property with code or from a variable.
5. If code, type the data type of the property with "as type"
etc.
HTH
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Custom list class
Charles said:
That wiki page is incredibly helpful. Thanks for pointing me to it (long ago!).
There is a wiki page on properties. I skimmed it and it looked correct, but possibly incomplete.
That wiki page is incredibly helpful. Thanks for pointing me to it (long ago!).
- DelphiGuy
- Posts: 116
11 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 7 guests