I've got errors
Assets/TextPierwszy.js(22,28): BCE0019: 'id' is not a member of 'Object'.
Assets/TextPierwszy.js(24,38): BCE0019: 'id' is not a member of 'Object'.
when trying to compile that script in UnityScript.
#pragma strict
private var pole : UI.Text;
public var Started = false;
public var Ludnosc = new Array();
public class Human {
public var id : byte;
public var gender : byte; // 0=k 1=m
public var age : byte;
public var pregnant : byte;
function Breed(partner) {
// Tu będzie logika rozmnażania
}
public var parents : int[]; //Najpierw podajemy ID matki, potem ID ojca.
}
function Test1() {
if(!Started) {
Started = true;
Ludnosc.push(new Human());
Ludnosc[0].id = 1; //Line number 22
Debug.Log(Ludnosc.length);
Debug.Log(Ludnosc[0].id); //Line number 24
}
}
How can I tell compiler to track Ludnosc[0] as instance of Human instead of tracking it at plain Object?
Or is there problem in other place? Also tried
public var Ludnosc : Human = new Array();
but this don't work too. :(
This is because when you initialize Ludnosc using:
public var Ludnosc = new Array();
you're creating an array of Object elements. As a result, when you try to access Ludnosc[0].id, Ludnosc[0] is treated an an Object and hence does not have id available to it.
To address this, either initialize Ludnosc as a built-in array like so:
public var Ludnosc : Human[];
Ludnosc = new Human[1]; // When you're initializing it
Ludnosc[0] = new Human(); // When you're populating it
Or, if you really want to use a JavaScript array, you can cast the Object to a Human when you access the value in Test1(), modify the typecasted version, then place it back into the array (haven't tested this code):
function Test1() {
if(!Started) {
Started = true;
Ludnosc.push(new Human());
var tempHuman = Ludnosc[0] as Human;
tempHuman.id = 1;
Ludnosc[0] = tempHuman; // Overwriting with the updated Human
Debug.Log(Ludnosc.length);
Debug.Log(tempHuman.id);
}
}
Hope this helps! Let me know if you have any questions.
Related
Whenever I try to access a variable within a class method, Flash gives the error message: Access of undefined variable
This is true for variables vertices, i, deltap, etc. below. All of these should be defined for the whole class, as far as I can see. What am I missing?
package
{
import flash.display.Shape;
import flash.display.Graphics;
import fl.motion.Color;
public dynamic class Quadrilateral extends Shape {
public var vertices:Array = new Array();
public var endvertices:Array;
public var angle:Number;
public var mycolor:Color;
private var steps:Number;
private var deltap:Array = new Array(4);
private var i:Number;
public function Quadrilateral(vertexlist, fillcolor, stepcount=100) {
vertices = vertexlist;
mycolor = fillcolor;
steps = stepcount;
drawme()
}
public static function setfinal(vertexlist) {
endvertices = vertexlist;
for (i=0;i<4;i++) {
deltap[i] = (endvertices[i] - vertices[i])/100;
}
}
}
You are missing that the method is static, which means that you cannot access non static members from inside it.
That method should not be static.
In Haxe, it is possible to get the class of an object with the following function:
Type.getClass(myObject);
If the object myObject is an instance of the class myClass, which contains a static field, I should be able to access this static field:
class MyClass
{
public static myStaticField:Int = 5;
}
public var myObject = new MyClass();
//expected trace: "5"
trace (Type.getClass(myObject).myStaticfield);
But the result is:
"Class <MyClass> has no field myStaticField."
Any idea why?
You need to use reflection to get such value:
class Test {
#:keep public static var value = 5;
static function main() {
var test = new Test();
var v = Reflect.field(Type.getClass(test), "value");
trace(v);
}
public function new() {}
}
Note that to prevent DCE (dead code elimination) I had to mark the static var with #:keep. Normally DCE is going to suppress that variable because it is never referred directly.
Working example here: http://try.haxe.org/#C1612
Try the Reflect class (Specifically the callMethod or getProperty functions).
I'm playing with the swift language and i have a question on get/set properties. I think that it makes no sense to let the inner variable be public when the value is managed by a computed property. So I think that making this private to the class is a good practise. As I'm still learning maybe some of you could give me other ideas to leave it public.
class aGetSetClass{
private var uppercaseString : String
var upperString : String {
get {
return uppercaseString
}
set (value) {
self.uppercaseString = value.uppercaseString
}
}
init(){
uppercaseString = "initialized".uppercaseString
}
}
var instance3 = aGetSetClass()
println(instance3.upperString) // INITIALIZED
instance3.upperString = "new"
// println(instance3.uppercaseString) // private no access
println(instance3.upperString) // NEW
instance3.upperString = "new123new"
println(instance3.upperString) // NEW123NEW
The only way I could think of public access is either to make it as private set and then use a public set function instead:
public private(set) uppercaseString: String
public func setUpperString(string: String) {
uppercaseString = string.uppercaseString
}
Or make it public and use a didSet which sets itself under a certain condition (very inefficient for long strings):
public uppercaseString: String {
didSet {
if uppercaseString != uppercaseString.uppercaseString {
uppercaseString = uppercaseString.uppercaseString
}
}
}
These implementations use direct public access but your version is in my perspective the better / "swifter" way.
This is the first time I've used flash builder (I usually just use flash itself for all my AS stuff). I've got a bunch of non static classes and one of them has an issue passing a parameter from a constructor to a private var.
private function init():void
{
var keys:Primes = new Primes();
var keyArray:Array = [["kdc",keys.getRandomPrime()],["client",keys.getRandomPrime()],["server",keys.getRandomPrime()]];
trace(keyArray);
kdc = new KeyDistCentre(keyArray);
client = new Client(keyArray[1][1]);
server = new Server(keyArray[2][1]);
}
It's the kdc = new line which is causing an issue, when I pass keyArray into it it has a problem assigning the value to the private var in the class.
package
{
public class KeyDistCentre extends Client
{
private var keyList:Array = new Array();
public function KeyDistCentre(keys:Array)
{
super(keys[0][1]);
keyList = keys; **ERROR**
}
public function generateTicket():Ticket
{
return null;
}
}
}
The weird thing is even when I comment out all the problematic lines, the exact same error with line reference occurs...
I am currently examining Moles from the outside while I wait for my VS 2010 license, and I wonder whether Moles allows me to:
provide the ability to assígn multiple mole delegates for a method being moled, perhaps at a test fixture setup level?
switch in runtime in my test case, which of my mole delegates must be invoked for the upcoming call(s) to the moled method being isolated?
Any hints?
Best Answer:
It is much easier and makes far more sense to include gating logic in the detour method, than using two stubs for the same method! For example, MyMethod reads data from three different files on disk, each requiring different mock data to be returned. We may detour System.IO.File.OpenRead and gate the return value by analyzing the input parameters of OpenRead:
TEST METHOD:
[TestMethod]
[HostType("Moles")]
public void Test()
{
System.IO.Moles.MFile.OpenReadString = filePath => {
var mockStream = new System.IO.FileStream();
byte[] buffer;
switch (filePath)
{
case #"C:\DataFile.dat":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
case #"C:\TextFile.txt":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
case #"C:\LogFile.log":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
}
return mockStream;
};
var target = new MyClass();
target.MyMethod();
}
TARGET TYPE:
using System.IO;
public class MyClass
{
public void MyMethod()
{
var fileAData = File.OpenRead(#"C:\DataFile.dat");
var fileBData = File.OpenRead(#"C:\TextFile.txt");
var fileCData = File.OpenRead(#"C:\LogFile.log");
}
}
Direct Answer to Your Questions:
Yes to #1: instantiate one type for each detour, and then use each for the desired behavior. And, yes to #2: act upon one instance of the mole type or the other. This requires addition of method input parameters or class constructor injection.
For example, MyMethod reads three data files from disk, and you need to pass back three different data mocks. MyMethod requires three parameters, an overtly intrusive solution. (Note input parameters are FileInfo type; because, System.IO>File is static and can not be instantiated: For example:
TEST METHOD:
[TestMethod]
[HostType("Moles")]
public void Test()
{
var fileInfoMoleA = new System.IO.Moles.MFileInfo();
fileInfoMoleA.OpenRead = () => { return new FileStream(); };
var fileInfoMoleB = new System.IO.Moles.MFileInfo();
fileInfoMoleB.OpenRead = () => { return new FileStream(); };
var fileInfoMoleC = new System.IO.Moles.MFileInfo();
fileInfoMoleC.OpenRead = () => { return new FileStream(); };
var target = new MyClass();
target.MyMethod(fileInfoMoleA, fileInfoMoleB, fileInfoMoleC);
}
TARGET TYPE:
using System.IO;
public class MyClass
{
// Input parameters are FileInfo type; because, System.IO.File
// is a static class, and can not be instantiated.
public void MyMethod(FileInfo fileInfoA, FileInfo fileInfoB, FileInfo fileInfoC)
{
var fileAData = fileInfoA.OpenRead();
var fileBData = fileInfoB.OpenRead();
var fileCData = fileInfoC.OpenRead();
}
}
UPDATE:
In response to #Chai comment, it is possible to create common methods, within the test project, that may be referenced as the mole detour delegate. For example, you may wish to write a common method that may be referenced by any unit test, that sets up a variety of pre-configured scenarios. The following example displays how a parameterized method could be used. Get creative -- they're just method calls!
TARGET TYPES:
namespace PexMoleDemo
{
public class MyClass
{
private MyMath _math;
public MyClass()
{
_math = new MyMath() { left = 1m, right = 2m };
}
public decimal GetResults()
{
return _math.Divide();
}
}
public class MyOtherClass
{
private MyMath _math;
public MyOtherClass()
{
_math = new MyMath() { left = 100m, right = 200m };
}
public decimal Divide()
{
return _math.Divide();
}
}
public class MyMath
{
public decimal left { get; set; }
public decimal right { get; set; }
public decimal Divide()
{
return left / right;
}
}
}
TEST METHODS:
ArrangeScenarios() sets up mole detours, by switching on the enumeration parameter. This allows the same scenarios to be erected, in a DRY manner, throughout many tests.
using System;
using Microsoft.Moles.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PexMoleDemo;
[assembly: MoledAssembly("PexMoleDemo")]
namespace TestProject1
{
[TestClass()]
public class ProgramTest
{
public enum Scenarios
{
DivideByZero,
MultiplyInsteadOfDivide
}
private void ArrangeScenario(Scenarios scenario)
{
switch (scenario)
{
case Scenarios.DivideByZero:
PexMoleDemo.Moles.MMyMath.AllInstances.rightGet =
instance => { return 0m; };
break;
case Scenarios.MultiplyInsteadOfDivide:
PexMoleDemo.Moles.MMyMath.AllInstances.Divide =
instance => { return instance.left * instance.right; };
break;
default:
throw new NotImplementedException("Invalid scenario.");
}
}
[TestMethod]
[HostType("Moles")]
[ExpectedException(typeof(DivideByZeroException))]
public void Test1()
{
ArrangeScenario(Scenarios.DivideByZero);
var target = new PexMoleDemo.MyClass();
var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
var left = math.left;
var right = math.right;
var actual = target.GetResults();
}
[TestMethod]
[HostType("Moles")]
public void Test2()
{
ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
// Perform some sort of test that determines if code breaks
// when values are multiplied instead of divided.
}
[TestMethod]
[HostType("Moles")]
[ExpectedException(typeof(DivideByZeroException))]
public void Test3()
{
ArrangeScenario(Scenarios.DivideByZero);
var target = new PexMoleDemo.MyOtherClass();
var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
var left = math.left;
var right = math.right;
var actual = target.Divide();
}
[TestMethod]
[HostType("Moles")]
public void Test4()
{
ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
// Perform some sort of test that determines if code breaks
// when values are multiplied instead of divided.
}
}
}