I'm working on some D bindings for an existing C library, and I have a bunch of function definitions, and a bunch of bindings for them. For example:
// Functions
void function(int) funcA;
long function() funcB;
bool function(bool) funcC;
char function(string) funcD;
// etc...
// Bindings
if(!presentInLibrary("func")) return false;
if(!bindFunction(funcA, "funcA")) return false;
if(!bindFunction(funcB, "funcB")) return false;
if(!bindFunction(funcC, "funcC")) return false;
if(!bindFunction(funcD, "funcD")) return false;
// etc...
This model is very similar to how Derelict handles OpenGL extension loading. However, this seems like a lot of redundant typing. I'd really like a way to express the "binding" portion above as something like:
BINDGROUP("func", "funcA", "funcB", "funcC", "funcD", ...); // Name of function group, then variable list of function names.
Is this something that can be done with mixins?
I used this when I was doing dynamic loading, while it doesn't answer your question you may be able to adapt it:
void function() a;
int function(int) b;
void function(string) c;
string bindFunctions(string[] funcs...)
{
string ret;
foreach (func; funcs)
{
ret ~= func ~ ` = cast(typeof(` ~ func ~ `))lib.getSymbol("` ~ func ~ `");`;
}
return ret;
}
mixin(bindFunctions("a", "b", "c"));
Here bindFunctions("a", "b", "c") returns a string that looks something like:
a = cast(typeof(a))lib.getSymbol("a");
b = cast(typeof(b))lib.getSymbol("b");
c = cast(typeof(c))lib.getSymbol("c");
Where lib.getSymbol() returns a pointer from dl_open() etc. Hope this helps.
I assume you meant string mixins? You can just make straight-forward use of D's vararg syntax:
string BINDGROUP(string functionGroup, string[] functions...)
{
// ...
}
mixin(BINDGROUP("func", "funcA", "funcB", "funcC", "funcD"));
I believe this is what you're looking for
template BINDGROUP(string group,T...){
alias BINDGROUP presentInLibrary("func") && BINDGROUPFUNCS!(T);
}
template BINDGROUPFUNCS(T...){
static if(T.length)alias BINDGROUPFUNCS true; // all is successful
else alias BINDGROUPFUNCS bindFunction(mixin(T), T) && BINDGROUPFuncts!(T[1..$]);
}
I'm using recursive template declaration here, you could also do this with foreach loops
Related
Is there a way in Rust to create a std::env::Args from a Vec<String> in order to use it in a #[test] function?
I wish to test a function that gets a std::env::Args as an argument, but I don't know how to create such an object with a list of arguments I supply for the test.
I wasn't able to figure this one out from the docs, the source nor from Google searches.
The fields of std::env::Args are not documented, and there doesn't appear to be a public function to create one with custom fields. So, you're outta luck there.
But since it's just "An iterator over the arguments of a process, yielding a String value for each argument" your functions can take a String iterator or Vec without any loss of functionality or type safety. Since it's just a list of Strings, it doesn't make much sense to arbitrarily limit your functions to strings which happen to come from the command line.
Looking through Rust's own tests, that's just what they do. There's a lot of let args: Vec<String> = env::args().collect();
There's even an example in rustbuild where they strip off the name of the program and just feed the list of arguments.
use std::env;
use bootstrap::{Config, Build};
fn main() {
let args = env::args().skip(1).collect::<Vec<_>>();
let config = Config::parse(&args);
Build::new(config).build();
}
And bootstrap::Config::parse() looks like so:
impl Config {
pub fn parse(args: &[String]) -> Config {
let flags = Flags::parse(&args);
...
I'm not a Rust expert, but that seems to be how the Rust folks handle the problem.
#Schwern's answer is good and it led me to this simpler version. Since std::env::Args implements Iterator with Item = String you can do this:
use std::env;
fn parse<T>(args: T)
where
T: Iterator<Item = String>,
{
for arg in args {
// arg: String
print!("{}", arg);
}
}
fn main() {
parse(env::args());
}
To test, you provide parse with an iterator over String:
#[test]
fn test_parse() {
let args = ["arg1", "arg2"].iter().map(|s| s.to_string());
parse(args);
}
I've wrote a little macro to make this easier, based on #Rossman's answer (and therefore also based on #Schwern's answer; thanks go to both):
macro_rules! make_string_iter {
($($element: expr), *) => {
{
let mut v = Vec::new();
$( v.push(String::from($element)); )*
v.into_iter()
}
};
}
It can be used in that way:
macro_rules! make_string_iter {
($($element: expr), *) => {
{
let mut v = Vec::new();
$( v.push(String::from($element)); )*
v.into_iter()
}
};
}
// We're using this function to test our macro
fn print_args<T: Iterator<Item = String>>(args: T) {
for item in args {
println!("{}", item);
}
}
fn main() {
// Prints a, b and c
print_args(make_string_iter!("a", "b", "c"))
}
Or try it out on the Rust Playground.
I'm not (yet) an expert in rust, any suggestions are highly welcome :)
I am trying to learn TypeScript, and need some advice on implementing generic collection types. I put the dictionary and HashSet in another question, here I'd like any advice on my list type.
Especially the ForEach-Operation looks a bit strange. I think I found it in another question here, and "improved" by returning true or false to give feedback if the iteration was stopped early or completed.
import { IForEachFunction } from "./IForEachFunction"
export class List<T> {
private _items: Array<T>;
public constructor() {
this._items = [];
}
public get Count(): number {
return this._items.length;
}
public Item(index: number): T {
return this._items[index];
}
public Add(value: T): void {
this._items.push(value);
}
public RemoveAt(index: number): void {
this._items.splice(index, 1);
}
public Remove(value: T): void {
let index = this._items.indexOf(value);
this.RemoveAt(index);
}
public ForEach(callback: IForEachFunction<T>): boolean {
for (const element of this._items) {
if (callback(element) === false) {
return false;
}
}
return true;
}
}
The ForEach-Iteration relies on an interface from another file:
export interface IForEachFunction<T> {
(callback: T): boolean | void;
}
You would use my list and the ForEach-Method like this:
let myList: List<a_type> = new List<a_type>();
let completed: boolean = myList.ForEach(xyz => {
// do something with xyz
return false; // aborts the iteration
return true; // continues with the next element
});
if (completed) // we can see what happened "during" the iteration
I think this is not bad, but I'd appreciate any input. I am not sure if I use the === correctly.
Another question which I really like to know: How could I define a function with the interface IForEachFunction? I do not really "re-use" that interface visibly, I always declare an anonymous method as shown above. If I wanted to call a method having the interface definition, is that possible?
Thanks!
Ralf
One problem I see is that you have an interface instance:
callback: IForEachFunction<T>
This contains a method called
callback()
But you only call callback once. You would have call callback() method inside your interface:
callback.callback()
Also your code looks like it is inspired by C# or Java. In TypeScript you would often just use an array. This simplifies certain code constructs.
As I come from a JS background this is how I'd call a function by name stored in a variable:
var obj = {
foobar: function(param) {
// do something
}
};
var key = "foobar";
obj[key](123);
Now I would like to recreate this in Swift, for example:
struct obj = {
func foobar(param) {
// do something
}
}
let key:String = "foobar"
obj[key](123)
The above code unfortunately gives Type 'obj.Type' has no subscript members
Is there any way to call functions by names in a Struct, Class or a Dictionary (if it's even possible to store functions in Dicts?)
EDIT - MORE CONTEXT:
I have a user-supplied array of things say:
let arr = ["apples", "oranges", "pears"]
but this array can be as long as 20 items. Based on each item of the array I need to perform certain action. So I iterate over the array:
for (key, _) in arr {
if (key == "apples") {
handleApples()
}
if (key == "oranges") {
handleOranges()
}
// and so on...
}
Sure, I can have a function with a simple switch that would consist of 20 cases but that's far from ideal. What if my array grows to say 100 items?
I was hoping to achieve something similar to this:
for (key, _) in arr {
myClass[key]()
}
Is there any way to call functions by names in a Struct, Class or a Dictionary (if it's even possible to store functions in Dicts?)
Yes you can store a function into a dictionary
Let's define a function type
typealias FuncType = () -> ()
and 2 functions
func func0() {
print("Apples")
}
func func1() {
print("Oranges")
}
Now we can create a dictionary where the key is String and the value is FuncType
let dict : [String:FuncType] = [
"Apples" : func0,
"Oranges" : func1
]
And of course we can invoke a function stored into the dictionary
dict["Apples"]?() // prints "Apples"
I think this might be what you're looking for:
var obj: [String: Int] = {
// do something, like call foobar(param) that's defined outside of the variable
// or just manipulate data directly in here
return ["foobar": 123]
// or whatever dictionary you want that matches the type you defined for obj
}()
Kind of tough to give you a better answer without you posting the kind of output or behavior you're looking for.
I'm working with Golang, and currently I'm doing some fun unit test with Testify, my file look like this
type myStruct struct {
field_1 string
}
func (self *myStruct) writeFirst() {
//doing something
//modify field_1
self.writeSecond()
}
func (self *myStruct) writeSecond() {
//doing something
}
In this case I'm testing writeFirst() but I'm trying to replace writeSecond() because it is using http stuff that I don't want to use because it access to internet.
I think that use a second struct and set myStruct as anonymous field will be the solution, but it's not working because me second struct and myStruct have a diferent context.
In this case I can't use mocks cause writeSecond is a method of the struct.
My test case looks like this:
func TestWriteFirst(t *testing.T) {
myStc := myStruct{}
assert.Equal(t,"My response", myStc.field_1)
}
All that I want is testing writeFirst without pass to writeSecond()
To illustrate the kind of refactoring mentioned by Not-a-Golfer in the comments, you could consider calling your second function only on an instance that is an interface:
type F2er interface {
Func2()
}
type S struct{ _f2 F2er }
var s = &S{}
func (s *S) f2() F2er {
if s._f2 == nil {
return s
}
return s._f2
}
func (s *S) Func1() {
fmt.Println("s.Func1")
s.f2().Func2()
}
Here: Func1 calls Func2 on s.f2(), not directly s.
If nothing has been set in s, s.f2() returns... itself: s
if s._f2 was replaced by any other struct which implements Func2, s.f2() returns that instance instead of itself.
See a complete example in this playground script.
Output:
TestFunc1
s.Func1
s.Func2
TestFunc1bis
s.Func1
testS.Func2 <=== different Func2 call
I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:
var f = function() { }
f.someValue = 3;
Now in TypeScript I can describe the type of this as:
var f: { (): any; someValue: number; };
However I can't actually build it, without requiring a cast. Such as:
var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;
How would you build this without a cast?
Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).
The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.
interface F { (): any; someValue: number; }
var f = <F>function () { }
f.someValue = 3
// type error
f.notDeclard = 3
This is easily achievable now (typescript 2.x) with Object.assign(target, source)
example:
The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.
Enforcing that this resolves to a known interface is also straight-forward. For example:
interface Foo {
(a: number, b: string): string[];
foo: string;
}
let method: Foo = Object.assign(
(a: number, b: string) => { return a * a; },
{ foo: 10 }
);
which errors due to incompatible typing:
Error: foo:number not assignable to foo:string
Error: number not assignable to string[] (return type)
caveat: you may need to polyfill Object.assign if targeting older browsers.
TypeScript is designed to handle this case through declaration merging:
you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.
Declaration merging lets us say that something is both a function and a namespace (internal module):
function f() { }
namespace f {
export var someValue = 3;
}
This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:
declare function f(): void;
declare namespace f {
export var someValue: number;
}
Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.
So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:
var f: { (): any; someValue: number; };
f = (() => {
var _f : any = function () { };
_f.someValue = 3;
return _f;
})();
Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.
EDIT: Simplified the code a bit.
Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:
function f () {}
f.someValue = 3; // fine
const g = function () {};
g.someValue = 3; // also fine
var h = function () {};
h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"
Reference and online example.
As a shortcut, you can dynamically assign the object value using the ['property'] accessor:
var f = function() { }
f['someValue'] = 3;
This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:
var val = f.someValue; // This won't work
var val = f['someValue']; // Yeah, I meant to do that
However, if you really want the type checking for the property value, this won't work.
I can't say that it's very straightforward but it's definitely possible:
interface Optional {
<T>(value?: T): OptionalMonad<T>;
empty(): OptionalMonad<any>;
}
const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
Optional.empty = () => OptionalCreator();
if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional
An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.
Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.
NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This departs from strong typing, but you can do
var f: any = function() { }
f.someValue = 3;
if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.
"You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)