how can I create a reference to a variable in specman? - reference

I have the following code in specman:
var x := some.very.long.path.to.a.variable.in.another.struct;
while (x == some_value) {
//do something that uses x;
//wait for something
//get a new value for x
x = some.very.long.path.to.a.variable.in.another.struct;
};
Now, it seems wasteful to write the assignment to x twice; once during initialization and once during the loop.
What I really want to use is a reference to the long variable name, so that I could do:
var x := reference to some.very.long.path.to.a.variable.in.another.struct;
while (x == some_value) {
//do something that uses x;
//wait for something
//no need to update x now since it's a reference
};
Can this be done in specman?

specman/e generally uses references for structs and lists, so if your variable type is either of it your second example should work. For integer or boolean I don't know a way to use a reference for a variable. Anyway, two ideas which might help you:
Add a pointer to the other struct and bind it in a config file:
struct a { other_variable : uint; };
struct b {
other_struct : a;
some_func() is {
var x : uint = other_struct.other_variable;
while (x == some_value) {
x = other_struct.other_variable;
};
};
};
extend cfg {
struct_a : a;
struct_b : b;
keep struct_b.other_struct == struct_a;
};
UPDATE: You can find some more information on this technique in this Team Specman Post.
Wrap your while loop in a function, there you can pass parameters by reference (see help pass reference):
some_func(x : *uint) is {
while (x == some_value) {
// stuff ...
};
};
Hope this helps!
Daniel

Related

Build variable length arguments array for #call

I've recently started learning Zig.
As a little project I wanted to implement a small QuickCheck [1] style helper library for writing randomized tests.
However, I can't figure out how to write a generic way to call a function with an arbitrary number of arguments.
Here's a simplified version that can test functions with two arguments:
const std = #import("std");
const Prng = std.rand.DefaultPrng;
const Random = std.rand.Random;
const expect = std.testing.expect;
// the thing we want to test
fn some_property(a: u64, b: u64) !void {
var tmp: u64 = undefined;
var c1 = #addWithOverflow(u64, a, b, &tmp);
var c2 = #addWithOverflow(u64, a, b, &tmp);
expect(c1 == c2);
}
// helper for generating random arguments for the function under test
fn gen(comptime T: ?type, rnd: Random) (T orelse undefined) {
switch (T orelse undefined) {
u64 => return rnd.int(u64),
f64 => return rnd.float(f64),
else => #compileError("unsupported type"),
}
}
/// tests if 'property' holds.
fn for_all(property: anytype) !void {
var rnd = Prng.init(0);
const arg_types = #typeInfo(#TypeOf(property)).Fn.args;
var i: usize = 0;
while (i < 100) {
var a = gen(arg_types[0].arg_type, rnd.random());
var b = gen(arg_types[1].arg_type, rnd.random());
var args = .{a, b}; // <-- how do I build args for functions with any number of arguments?
try #call(.{}, property, args);
i += 1;
}
}
test "test" {
try for_all(some_property);
}
I've tried a few different things, but I can't figure out how to get the above code to work for functions with any number of arguments.
Things I've tried:
Make args an array and fill it with an inline for loop. Doesn't work since []anytype is not a valid type.
Use a bit of comptime magic to build a struct type whose fields hold the arguments for #call. This hits a TODO in the compiler: error: TODO: struct args.
Write generic functions that return an appropriate argument tuple call. I don't really like this one, since you need one function for every arity you want to support. But it doesn't seem to work anyway since antype is not a valid return type.
I'm on Zig 0.9.1.
Any insight would be appreciated.
[1] https://hackage.haskell.org/package/QuickCheck
This can be done with std.meta.ArgsTuple (defined in this file of the zig standard library)
const Args = std.meta.ArgsTuple(#TypeOf(property));
var i: usize = 0;
while (i < 1000) : (i += 1) {
var args: Args = undefined;
inline for (std.meta.fields(Args)) |field, index| {
args[index] = gen(field.field_type, rnd.random());
}
try #call(.{}, property, args);
}
The way this works internally is it constructs a tuple type with #Type(). We can then fill it with values and use it to call the function.

How to access rust variables outside the scope?

My code look like this
fn main() {
// some other codes goes here
let int = 1;
if int == 1 {
let x = "yes";
} else {
let x = "no";
}
if x == "yes" {
// some other codes goes here
println!("yes");
} else if x == "no" {
// some other codes goes here
println!("no")
}
}
When I run this I get this
error[E0425]: cannot find value `x` in this scope
--> src/main.rs:9:8
|
9 | if x == "yes" {
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> src/main.rs:12:15
|
12 | } else if x == "no" {
| ^ not found in this scope
While searching for a solution I came across this post How do I access a variable outside of an `if let` expression? but could not able to understand the reason or its solution?
Easiest is by far to code it such that it is in scope in the first place.
You can assign variable with the result of a statement in a single assignment.
If you can make it as a one-liner, it also makes it arguably more readable.
If the actual processing is too long, nothing prevents you from just... making it a proper function.
let x = if int == 1 { "yes" } else { "no" };
// rest of the code accessing x.
Alternatively, the compiler will let you declare unassigned variables if you properly assign them later, with all the compile-time safety checks in place. Read the docs on RAII (Resource Acquisition Is Initialization) RAII Docs to see more how it works. In practice, it's just as simple as this:
let x;
if i == 1 {
x = "yes";
}
else {
x = "no";
}
// keep doing what you love
The compiler will error if there's a logic path where x doesn't get initialized, or if it gets initialized as a different type.
Notice you also do not need to declare it as mut, as the first value it gets will stay immutable. Unless you do want to change it afterwards, obviously.
You can't access a variable which is out of scope. But you use a workaround and set the variable in the same scope.
fn main(){
let int = 1;
let x = if int == 1 {
"yes"
} else {
"no"
};
if x == "yes" {
println!("yes");
} else if x == "no" {
println!("no");
}
}
In Rust each variable has a scope that starts where the variable in initialized. In you problem you try to use the variable x which is created inside of the if int == 1 and the if x == "yes", since if statements have a separate scope from the function main you cannot create a variable inside of your if statement and expect it not to be cleared when you leave scope. The simplest solution is to initialize the variable x where you want to have it used in if x == "yes", so let's say that we want the scope of x to start in main by putting let x; in main. In Rust you may have variable from the larger scope be visible to the scopes that are within that larger scope where the variable in initialized, so assigning the variable from the scope of an if statement is perfectly valid.
Please take a look at https://doc.rust-lang.org/rust-by-example/variable_bindings/scope.html for more information.
fn main() {
let x;
// some other codes goes here
let int = 1;
if int == 1 {
x = "yes";
} else {
x = "no";
}
if x == "yes" {
// some other codes goes here
println!("yes");
} else if x == "no" {
// some other codes goes here
println!("no")
}
}
But you could get rid of the two if statements and just use match:
fn main() {
let myint = 1;
match myint {
1 => {println!("yes")}
_ => {println!("no")}
}
}
The question
I believe you are asking what does this error mean?
To answer that, one must first answer, what is scope?
The answer
Scope, in lay terms, is the section of code where a variable exists.
So when the error says not found in this scope, it means the variable does not exist here.
An example
fn main() {
let a_bool = true;
let main_scope_x = 0;
if a_bool == true {
let if_scope_x = 1;
} // if_scope_x stops existing here!
println!("main x has the value {}", main_scope_x);
println!("if x has the value {}", if_scope_x); // this will cause an error, if_scope_x does not exist outside the if expression.
}
Further info
https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html
(Read the book! It's very good!)

Define a literal Javascript object so a property referenced directly calls a function and not its sub-ordinates [duplicate]

JavaScript allows functions to be treated as objects--if you first define a variable as a function, you can subsequently add properties to that function. How do you do the reverse, and add a function to an "object"?
This works:
var foo = function() { return 1; };
foo.baz = "qqqq";
At this point, foo() calls the function, and foo.baz has the value "qqqq".
However, if you do the property assignment part first, how do you subsequently assign a function to the variable?
var bar = { baz: "qqqq" };
What can I do now to arrange for bar.baz to have the value "qqqq" and bar() to call the function?
It's easy to be confused here, but you can't (easily or clearly or as far as I know) do what you want. Hopefully this will help clear things up.
First, every object in Javascript inherits from the Object object.
//these do the same thing
var foo = new Object();
var bar = {};
Second, functions ARE objects in Javascript. Specifically, they're a Function object. The Function object inherits from the Object object. Checkout the Function constructor
var foo = new Function();
var bar = function(){};
function baz(){};
Once you declare a variable to be an "Object" you can't (easily or clearly or as far as I know) convert it to a Function object. You'd need to declare a new Object of type Function (with the function constructor, assigning a variable an anonymous function etc.), and copy over any properties of methods from your old object.
Finally, anticipating a possible question, even once something is declared as a function, you can't (as far as I know) change the functionBody/source.
There doesn't appear to be a standard way to do it, but this works.
WHY however, is the question.
function functionize( obj , func )
{
out = func;
for( i in obj ){ out[i] = obj[i]; } ;
return out;
}
x = { a: 1, b: 2 };
x = functionize( x , function(){ return "hello world"; } );
x() ==> "hello world"
There is simply no other way to acheive this,
doing
x={}
x()
WILL return a "type error". because "x" is an "object" and you can't change it. its about as sensible as trying to do
x = 1
x[50] = 5
print x[50]
it won't work. 1 is an integer. integers don't have array methods. you can't make it.
Object types are functions and an object itself is a function instantiation.
alert([Array, Boolean, Date, Function, Number, Object, RegExp, String].join('\n\n'))
displays (in FireFox):
function Array() {
[native code]
}
function Boolean() {
[native code]
}
function Date() {
[native code]
}
function Function() {
[native code]
}
function Number() {
[native code]
}
function Object() {
[native code]
}
function RegExp() {
[native code]
}
function String() {
[native code]
}
In particular, note a Function object, function Function() { [native code] }, is defined as a recurrence relation (a recursive definition using itself).
Also, note that the answer 124402#124402 is incomplete regarding 1[50]=5. This DOES assign a property to a Number object and IS valid Javascript. Observe,
alert([
[].prop="a",
true.sna="fu",
(new Date()).tar="fu",
function(){}.fu="bar",
123[40]=4,
{}.forty=2,
/(?:)/.forty2="life",
"abc".def="ghi"
].join("\t"))
displays
a fu fu bar 4 2 life ghi
interpreting and executing correctly according to Javascript's "Rules of Engagement".
Of course there is always a wrinkle and manifest by =. An object is often "short-circuited" to its value instead of a full fledged entity when assigned to a variable. This is an issue with Boolean objects and boolean values.
Explicit object identification resolves this issue.
x=new Number(1); x[50]=5; alert(x[50]);
"Overloading" is quite a legitimate Javascript exercise and explicitly endorsed with mechanisms like prototyping though code obfuscation can be a hazard.
Final note:
alert( 123 . x = "not" );
alert( (123). x = "Yes!" ); /* ()'s elevate to full object status */
Use a temporary variable:
var xxx = function()...
then copy all the properties from the original object:
for (var p in bar) { xxx[p] = bar[p]; }
finally reassign the new function with the old properties to the original variable:
bar = xxx;
var A = function(foo) {
var B = function() {
return A.prototype.constructor.apply(B, arguments);
};
B.prototype = A.prototype;
return B;
};
NB: Post written in the style of how I solved the issue. I'm not 100% sure it is usable in the OP's case.
I found this post while looking for a way to convert objects created on the server and delivered to the client by JSON / ajax.
Which effectively left me in the same situation as the OP, an object that I wanted to be convert into a function so as to be able to create instances of it on the client.
In the end I came up with this, which is working (so far at least):
var parentObj = {}
parentObj.createFunc = function (model)
{
// allow it to be instantiated
parentObj[model._type] = function()
{
return (function (model)
{
// jQuery used to clone the model
var that = $.extend(true, null, model);
return that;
})(model);
}
}
Which can then be used like:
var data = { _type: "Example", foo: "bar" };
parentObject.createFunc(data);
var instance = new parentObject.Example();
In my case I actually wanted to have functions associated with the resulting object instances, and also be able to pass in parameters at the time of instantiating it.
So my code was:
var parentObj = {};
// base model contains client only stuff
parentObj.baseModel =
{
parameter1: null,
parameter2: null,
parameterN: null,
func1: function ()
{
return this.parameter2;
},
func2: function (inParams)
{
return this._variable2;
}
}
// create a troop type
parentObj.createModel = function (data)
{
var model = $.extend({}, parentObj.baseModel, data);
// allow it to be instantiated
parentObj[model._type] = function(parameter1, parameter2, parameterN)
{
return (function (model)
{
var that = $.extend(true, null, model);
that.parameter1 = parameter1;
that.parameter2 = parameter2;
that.parameterN = parameterN;
return that;
})(model);
}
}
And was called thus:
// models received from an AJAX call
var models = [
{ _type="Foo", _variable1: "FooVal", _variable2: "FooVal" },
{ _type="Bar", _variable1: "BarVal", _variable2: "BarVal" },
{ _type="FooBar", _variable1: "FooBarVal", _variable2: "FooBarVal" }
];
for(var i = 0; i < models.length; i++)
{
parentObj.createFunc(models[i]);
}
And then they can be used:
var test1 = new parentObj.Foo(1,2,3);
var test2 = new parentObj.Bar("a","b","c");
var test3 = new parentObj.FooBar("x","y","z");
// test1.parameter1 == 1
// test1._variable1 == "FooVal"
// test1.func1() == 2
// test2.parameter2 == "a"
// test2._variable2 == "BarVal"
// test2.func2() == "BarVal"
// etc
Here's easiest way to do this that I've found:
let bar = { baz: "qqqq" };
bar = Object.assign(() => console.log("do something"), bar)
This uses Object.assign to concisely make copies of all the the properties of bar onto a function.
Alternatively you could use some proxy magic.
JavaScript allows functions to be
treated as objects--you can add a
property to a function. How do you do
the reverse, and add a function to an
object?
You appear to be a bit confused. Functions, in JavaScript, are objects. And variables are variable. You wouldn't expect this to work:
var three = 3;
three = 4;
assert(three === 3);
...so why would you expect that assigning a function to your variable would somehow preserve its previous value? Perhaps some annotations will clarify things for you:
// assigns an anonymous function to the variable "foo"
var foo = function() { return 1; };
// assigns a string to the property "baz" on the object
// referenced by "foo" (which, in this case, happens to be a function)
foo.baz = "qqqq";
var bar = {
baz: "qqqq",
runFunc: function() {
return 1;
}
};
alert(bar.baz); // should produce qqqq
alert(bar.runFunc()); // should produce 1
I think you're looking for this.
can also be written like this:
function Bar() {
this.baz = "qqqq";
this.runFunc = function() {
return 1;
}
}
nBar = new Bar();
alert(nBar.baz); // should produce qqqq
alert(nBar.runFunc()); // should produce 1

Do we have to return value at setter?

In haxe documentation of properties, there is the example:
class C {
public var x(get,set) : Int;
function get_x(){ return 123; }
function set_x(value){
doSomethingWith(value);
return 123;
}
}
But why do we have to return a value in setter of x above? is there a good reason?
The reason is, in Haxe, the assignment expression does return a value, eg.
var a;
trace(a = 3.14);//3.14
It is natural since we can chain assignments together:
var test = a = 3.14; //test will be 3.14
For example there is a weird class,
class Weird {
public function new():Void {}
public var x(get, set):Int;
function get_x() return x;
function set_x(v:Int):Int {
x = v;
return 123;
}
}
var weird = new Weird();
trace(weird.x = 456); //123
trace(weird.x); //456
var test = weird.x = 456; //test will be 123
But of course, usually we simply return the input of the setter, because it is more logical:
function set_x(v:Int):Int {
return x = v;
}
Sometimes it's just nice to have a setter function return the previous value, so you can code like this:
oldval=set(newval);
do_something();
set(oldval);
to temporarily set a new value, then restore the old one after you've finished.

Why do setters need to return a value in Haxe?

I was recently tripped up by the fact that the expected type of a setter that sets an Int is Int -> Int.
Why does a setter return a value? What significance does this value have?
Small addition to other answers over here, it allows you to do this:
x = y = z = 5;
The value that the setter returns is the value of the assignment expression.
For instance, if you were to do something like this:
public var x(setX, getX): Int
public function setX(val: Int): Int {
return 5;
}
static function main() {
neko.Lib.print(x = 2); // Prints 5
}
Haxe would print out 5. The setter returns the value of the set expression. Of course, it's a nonsensical value in this case.
In the real world, it permits a way of implementing copy by value on assignment, eg:
public var pos(set_pos, default):Point;
function set_pos(newPos:Point) {
pos.x = newPos.x
pos.y = newPos.y;
return pos;
}
And also of having a sensible return when implementing setters that can fail, eg:
public var positiveX(default, set_positiveX):Int;
function set_positiveX(newX:Int) {
if (newX >= 0) x = newX;
return x;
}
trace(x = 10); // 10
trace(x = -4); // 10
trace(x); // 10
Whereas you would otherwise get something like this:
trace(x = 10); // 10
trace(x = -4); // -4
trace(x); // 10
Which is what happens in AS3 even if the setter does not modify the value. If you could not do this, clearly the first, where x = -4 returns 10 is better :)

Resources