= Cobra Code Examples = Some highlights of Cobra code and syntax ( on .Net). These are selected cobra code samples for the same items as in [http://www.harding.edu/fmccown/vbnet_csharp_comparison.html VB and C# comparison]. == Program Structure == {{{ #!cobra #use System # already defaulted in namespace Hello class HelloWorld def main is shared name = "Cobra" args = CobraCore.commandLineArgs # See if an argument was passed from the command line # (first arg is progname) if args.count == 2 name = args[1] Console.writeLine("Hello, " + name + "!") #print "Hello, [name]!" }}} == Comments == {{{ #!cobra # Single line comment /# Multiple lines #/ # XML comments on single line /# XML comments on multiple lines #/ }}} == Data Types == These are as per .Net (using .Net naming rather than C#) {{{ #!cobra # Value Types bool uint8 # byte char int16, uint16, int, uint, int64, uint64 # short, ushort, int, uint, long, ulong float, float32, float64 #float, double Decimal DateTime #(not a built-in C# type) Struct Enum (enumerations) #Reference Types Object String arrays Sigs/Delegates #Initializing ( the explicit typing (clause 'as ????' ) is optional, types are inferred from initialisation) correct as bool = true b as uint8 = 0x2A # hex person as Object? = nil name as String = "Dwight" grade as char = c'B' today as DateTime= DateTime.parse("12/31/2010 12:15:00 PM") amount as decimal = 35.99 gpa as float = 2.9f pi as float64 = 3.14159265_f64 lTotal as int64 = 123456_i64 sTotal as int16 = 123 usTotal as uint16 = 123 uiTotal as uint = 123 # or 123u ulTotal as uint64 = 123 # or 123u64 #Nilable Types x as int? = nil #Anonymous Types # Havent worked out how Cobra handle these examples yet... #var stu = new {Name = "Sue", Gpa = 3.5} #var stu2 = new {Name = "Bob", Gpa = 2.9} # no Key equivalent #Implicitly Typed Local Variables s = "Hello!" nums = @[ 1, 2, 3 ] #init from array literal hero = SuperHero("Batman") #Type Information x as int? = 0 # Nilable int Console.writeLine(x.getType) # Prints System.Int32 Console.writeLine(sharp'typeof(int)') # Prints System.Int32 Console.writeLine(x.getType.name) # prints Int32 #Type Conversion / Casting d = 3.5f i = Convert.toInt32(d) # Set to 4 (rounds) i1 as int = d to int # set to 3 (truncates decimal) }}} == Constants == {{{ #!cobra const MAX_STUDENTS as int = 25 # Can set to a const or var; may be initialized in a constructor var MIN_DIAMETER as float is readonly= 4.93f }}} == Enumerations == {{{ #!cobra enum Action Start, Stop, Rewind, Forward enum Status Flunk = 50 Pass = 70 Excel = 90 a = Action.Stop if a <> Action.Start Console.WriteLine(a + " is " + (int) a); # Prints "Stop is 1" Console.writeLine(Status.Pass to int) # Prints 70 Console.writeLine(Status.Pass) # Prints Pass }}} == Operators == {{{ #!cobra #Comparison == < > <= >= <> # Arithmetic + - * / % (mod) / (integer division if both operands are ints) Math.Pow(x, y) #Assignment = += -= *= /= %= &= |= ^= <<= >>= # +=1 -=1 # ++, -- No post increment/decrement #Bitwise & | ^ ~ << >> #Logical and or not #Note: and and or perform short-circuit logical evaluations #String Concatenation + }}} == Choices == {{{ #!cobra # Nil-coalescing operator x = y ? 5 # if y != null then x = y, else x = 5 # non nil coalescing x = y ! y.parseIt # if y nil x = nil else x = y.parseIt() # Ternary/Conditional operator greeting = if(age < 20, "What's up?", "Hello") if age < 20 greeting = "What's up?" else greeting = "Hello" # Multiple statements must be indented following if x <> 100 and y < 5 x *= 5 y *= 2 # braces not needed around condition expressions unless complicated if x > 5 x *= y else if x == 5 or y % 2 == 0 x += y else if x < 10 x -= y else x /= y # alternatively (1 liners) if x > 5, x *= y else if x == 5 or y % 2 == 0, x += y else if x < 10, x -= y else, x /= y # indented action blocks, breaks not needed case color # Must be integer, character, enumeration or string on "pink" or "red" #constants r++ on "blue" b++ on "green" g++ else other++ # 1 liners case color on 'pink' or 'red', r++ on 'blue', b++ on 'green', g++ else, other++ }}} == Loops == {{{ #!cobra # re-test Loops: # no "until" keyword while c < 10 c += 1 for c in 2 : 11 : 2 # start: stop : step Console.writeLine(c) #print c #Post-test Loop: post while c < 10 c += 1 # Array or collection looping names = {"Fred", "Sue", "Barney"} for s in names Console.writeLine(s) # print s # Breaking out of loops i = 0 while true if i == 5 break i += 1 # Continue to next iteration for i in 0 : 5 if i < 4 continue print i #same as Console.writeLine(i) # Only prints 4 }}} == Arrays == #Preference is for (typed) collections rather than arrays {{{ #!cobra nums as int[] = @[1, 2, 3] for i in 0 : nums.length Console.writeLine(nums[i]) # 5 is the size of the array names as String[]= String[](5) names[0] = 'David'; names[5] = "Bobby"; # Throws System.IndexOutOfRangeException # Add two elements, keeping the existing values Array.resize(ref names, 7) # multi dim and jagged arrays not well supported (use Collections) twoD = sharp'new float[rows, cols]' twoD[2,0] = 4.5f jagged as int[][] = sharp'new int[3][] { new int[5], new int[2], new int[3] }' jagged[0][4] = 5 }}} As a collection {{{ #!cobra nums = [1, 2, 3] for i in 0 : nums.count print nums[i] # 5 is the size of the array names = List(5) names[0] = "David"; names[5] = "Bobby"; # Throws System.IndexOutOfRangeException }}} == Functions == {{{ #!cobra # Pass by value (in, default), in/out reference (inout), and reference (out) def testFunc(x as int, y as inout int, z as out int) x += 1 y += 1 z = 5 # Accept variable number of arguments def sum(nums as vari int) as int sum as int = 0 for i in nums sum += i return sum def sayHello(name as String, prefix = "") Console.writeLine("Greetings, " + prefix + " " + name) def main a = 1 b = 1 c as int # c doesn't need initializing .testFunc(a, inout b, out c) Console.writeLine("{0} {1} {2}", a, b, c) # 1 2 5 assert c == 5 and b == 2 total = .sum(4, 3, 2, 1) # returns 10 assert total == 10 .sayHello("Strangelove", "Dr.") .sayHello("Mom") }}} == Strings == {{{ #!cobra # Escape sequences # \r # carriage-return # \n # line-feed # \t # tab # \\ # backslash # Can use either " or ' to delimit String literals # preference is for ' unless string contains ', then use " # String concatenation school = "Harding\t" school = school + "University" # school is "Harding (tab) University" school += "University" # Same thing school += 'University' # Same thing # Chars letter = school[0] # letter is H letter = 'Z' # letter is Z letter = Convert.toChar(65) # letter is A letter = 65 to Char # same thing word = school.toCharArray # word holds Harding # String literal string filename = r'c:\temp\x.dat' # Same as "c:\\temp\\x.dat" # String comparison mascot = 'Bisons' # or mascot = "Bisons" if mascot == "Bisons" # true if mascot.equals('Bisons') # true if mascot.toUpper.equals('BISONS') # true if mascot.compareTo('Bisons') == 0 # true # String matching - No Like equivalent, use Regex # Substring s = mascot.substring(2, 3) # s is "son" # Replacement s = mascot.replace('sons', 'nomial') # s is "Binomial" # Split names = 'Michael,Dwight,Jim,Pam' parts = names.split(','.toCharArray()) # One name in each slot #or parts = names.split([ c',']) # Date to string DateTime dt = DateTime(1973, 10, 12) s = dt.toString('MMM dd, yyyy') # Oct 12, 1973 # int to string x = 2 y = x.toString() # y is "2" # string to int x = Convert.toInt32('-5') # x is -5 # Mutable string buffer = System.Text.StringBuilder('two ') buffer.append('three ') buffer.insert(0, 'one ') buffer.replace('two', 'TWO') Console.writeLine(buffer) # Prints "one TWO three" }}} == Regular Expressions == {{{ #!cobra use System.Text.RegularExpressions # Match a string pattern r = Regex(r'j[aeiou]h?. \d:*', RegexOptions.IgnoreCase | RegexOptions.Compiled) if r.match('John 3:16').success # true Console.writeLine("Match") # Find and remember all matching patterns s = 'My number is 305-1881, not 305-1818.' r = Regex(r'(\\d+-\\d+)') # Matches 305-1881 and 305-1818 m as Match = r.match(s) while m.success #Console.writeLine("Found number: " + m.groups[1].toString + " at position " + m.groups[1].index.toString) print 'Found number: [m.groups[1]] at position [m.groups[1].index]' m = m.nextMatch to ! # Remember multiple parts of matched pattern r = Regex(r'(\d\d):(\d\d) (am|pm)') m = r.match("We left at 03:15 pm.") if m.success Console.writeLine("Hour: " + m.groups[1].toString) # 03 Console.writeLine("Min: " + m.groups[2].toString) # 15 Console.writeLine("Ending: " + m.groups[3].toString) # pm # Replace all occurrances of a pattern r = Regex(r'h\\w+?d', RegexOptions.IgnoreCase) s = r.replace("I heard this was HARD!", "easy") # I easy this was easy! # Replace matched patterns s = Regex.replace('123 < 456', r'(\d+) . (\d+)', '$2 > $1') # 456 > 123 # Split a string based on a pattern names = 'Michael, Dwight, Jim, Pam' r = Regex(r',\s*') parts = r.split(names) # One name in each slot }}} == Exceptions == {{{ #!cobra # Throw an exception up = Exception('Something is really wrong.') throw up # ha ha # Catch an exception try y = 0 x = 10 / y catch ex as Exception # Argument is optional, no "When" keyword Console.writeLine(ex.message) finally Microsoft.VisualBasic.Interaction.beep }}} == Namespaces == {{{ #!cobra namespace Harding.Compsci.Graphics ... # or namespace Harding namespace Compsci namespace Graphics ... use Harding.Compsci.Graphics }}} == Classes and Interfaces == {{{ #!cobra ## Access Modifiers public # default private internal protected protected internal #Class Modifiers abstract shared #Method Modifiers abstract shared virtual #default #No Module equivalent - just use static class # Partial classes class Competition is partial ... # Inheritance class FootballGame inherits Competition ... # Interface definition interface IAlarmClock def ring # public returns void by default pro currentDateTime as DateTime from var } # Extending an interface interface IAlarmClock inherits IClock ... } # Interface implementation class WristWatch implements IAlarmClock, ITimer def ring Console.writeLine('Wake up!') pro triggerDateTime as DateTime from var ... }}} == Constructors and Destructors == {{{ #!cobra class SuperHero inherits Person var powerLevel as int is private var name as String is private # Default constructor cue init .powerLevel = 0 .name = 'Super Bison' cue init(powerLevel as int) base.init('Super Bison') # Call other constructor .powerLevel = powerLevel cue init(name as String) base.init(name) # Call base classes' constructor .name = name cue init is shared # Static constructor invoked before 1st instance is created cue finalize # Destructor implicitly creates a Finalize method }}} == Using Objects == {{{ #!cobra hero as SuperHero? = SuperHero() # No "With" but can use property initializers hero = SuperHero(name = "SpamMan", powerLevel = 3) hero.defend("Laura Jones") SuperHero.rest # Calling static method hero2 = hero # Both reference the same object hero2.name = 'WormWoman' Console.writeLine(hero.name) # Prints WormWoman hero = nil # Free the object if hero == nil # or if not hero hero = SuperHero() obj as Object = SuperHero() if obj inherits SuperHero Console.writeLine("Is a SuperHero object.") # Mark object for quick disposal using reader as StreamReader = File.openText("test.txt") line as String? while (line = reader.readLine) <> nil Console.writeLine(line) }}} == Structs == {{{ #!cobra struct Student var name as String var gpa as float cue init(name as String, gpa as float) .name = name .gpa = gpa stu = Student("Bob", 3.5f) stu2 = stu stu2.name = "Sue" Console.writeLine(stu.name) # Prints Bob Console.writeLine(stu2.name) # Prints Sue }}} == Properties == {{{ #!cobra # Auto-implemented properties pro name as String from var get size as int from var # Set default value in constructor # Traditional property implementation var name as String is private # private backing variable #or #var __name as String #private #var _name as String #protected pro Name as String get return .name # return __name set .name = value #__name =value # Read-only property var powerLevel as int is private # private backing variable get powerlevel from var #alternatively var __powerLevel = 0 # inferred as type int, private get powerlevel from var # Write-only property var height as double is private # private backing variable set height as double .height = if(value < 0, 0, value) }}} == Generics == {{{ #!cobra # Enforce accepted data type at compile-time numbers = List() numbers.add(2) numbers.add(4) .displayList(numbers) # Function can display any type of List def displayList(List list) for item as T in list Console.writeLine(item) # Class works on any data type class SillyList list as T[] = T[](10) rand as Random = Random() public void add(item as T) list[rand.next(10)] = item public getItem as T return list[rand.next(10)] } # Limit T to only types that implement IComparable def maximum(items as vari T) where T must be IComparable max as T = items[0] for item in items if item.compareTo(max) > 0 max = item return max }}} == Delegates and Lambda Expresssions == {{{ #!cobra sig HelloDelegate(s as String) # returns void def sayHello(s as String) Console.writeLine('Hello, ' + s) # C# 1.0 delegate syntax with named method hello as HelloDelegate = ref .sayHello hello('World') # Or hello.Invoke('World') # C# 2.0 delegate syntax with anonymous method # method body indented on lines following do(args) hello2 as HelloDelegate = do(s as String) Console.WriteLine('Hello, ' + s) hello2("World") # C# 3.0 delegate syntax with lambda expression HelloDelegate hello3 as HelloDelegate = do(s as string)=Console.writeLine('Hello, ' + s) hello3("World") # Use Func delegate to call Uppercase convert as Func = ref .uppercase Console.writeLine(convert("test")) def uppercase(s as String) return s.toUpper # Declare and invoke Func using a lambda expression Console.WriteLine( Funcdo(num as int) = num + 1)(2)) # Pass lamba expression as an argument TestValues(do(x, y) = x % y == 0) void TestValues(Func f) if f(8, 4) Console.writeLine("true") else Console.writeLine("false") }}} == Events == {{{ #!cobra sig MsgArrivedEventHandler(message as String) event MsgArrivedEvent as MsgArrivedEventHandler # listen EVENT_NAME, METHOD_NAME listen MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback) raise MsgArrivedEvent, "Test message" # Throws exception if obj is null #ignore EVENT_NAME, METHOD_NAME ignore MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback) using System.Windows.Forms myButton = Button() listen myButton.click, System.EventHandler(ref .myButton_Click) def myButton_Click(sender as Object, e as System.EventArgs ) MessageBox.show(this, "Button was clicked", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information) }}} == LINQ == TBI {{{ #!cobra }}} == Attributes == {{{ #!cobra # Attribute can be applied to anything class IsTestedAttribute inherits Attribute pass # Attribute can only be applied to classes or structs class AuthorAttribute inherits Attribute has AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct) pro name as String from var pro version as int from var cue init(name as String ) .name = name; .version = 0; class Shape has Author("Sue", version = 3) def move has IsTested # Do something... }}} == Console I/O == {{{ #!cobra Console.write("What's your name? ") name as String = Console.readLine Console.write('How old are you? ') age as int = Convert.toInt32(Console.readLine) Console.writeLine("{0} is {1} years old.", name, age) # or Console.writeLine(name + " is " + age + " years old.") c as int = Console.read # Read single char Console.writeLine(c) # Prints 65 if user enters "A" # alternatively print "What's your name? " stop name = Console.readLine print 'How old are you? ' stop age = Convert.toInt32(Console.readLine) print '[name] is [age] years old.' # or print String.format('{0} is {1} years old.', name, age) c as int = Console.read # Read single char print c # Prints 65 if user enters "A" }}} == File I/O == {{{ #!cobra #use System.IO # already autoloaded # Write out to text file writer as StreamWriter = File.createText(r'c:\myfile.txt') writer.writeLine('Out to file.') writer.close # Read all lines from text file reader as StreamReader = File.openText(r'c:\myfile.txt') line = reader.readLine while line Console.writeLine(line) line = reader.readLine reader.close # Write out to binary file str as String = "Text data" num = 123 binWriter = BinaryWriter(File.openWrite(r'c:\myfile.dat')) binWriter.write(str) binWriter.write(num) binWriter.close # Read from binary file binReader = BinaryReader(File.openRead(r'c:\myfile.dat')) str = binReader.readString num = binReader.readInt32 binReader.close }}} Return to wiki:WikiStart