Say I have two files:
foo.re
bar.re
Say I now have, at the top of bar.re
open MyProject.Foo;
This fails to compile with:
This module is not a structure; it has type
(module MyProject.Foo)
If I rerun compilation, everything works fine
If I change that line to just open Foo; everything compiles fine.
Why am I observing this behaviour?
ReasonML treats each file as a module, the practice is to uppercase the file name so
Foo.re
Bar.re
let's also suppose that we define a function in Foo call bar and another in Bar call foo.
so we would have:
/* Inside Foo.re */
let bar = string => {}
/* Inside Bar.re */
let foo = string => {}
from with another module, which we have called Main.re, we can reference the above as.
let myResult = Foo.bar("happy");
let ourResult = Bar.foo("days);
or
open Foo, Bar;
let myResult = bar("happy");
let ourResult = foo("days");
So when asked for open MyProject.Foo, you were asking for the submodule Foo within the module MyProject, which does not exist. Of course, if you created MyProject.re and added a module to that file called Foo, then your open MyProject.Foo would work fine.
Further references:
The underlying Ocaml which the reasonML modules are based on.
The Basic modules section from Axel Rauschmayer book on ReasonML
Related
In ES6, I want to do something like
class Foo extends Bar {
#Map('toCall')
someFunction() {
...
}
}
and later
foo = new Foo();
Foo.MAGIC_LOOKUP_TABLE['toCall'](foo);
in order to effectively call foo.someFunction();.
The intended use case is to let the programmer in charge of Foo dictate which function should be called only with a decorator change.
However, when writing:
export function Map(str) {
return function(target, name, descriptor) {
// ???
};
}
I can not for the life of me figure out how to get anything like Foo where you see ??? above. target seems to be a prototype value shared by all subclasses of Bar that attempt to use #Map.
How can I best achieve this? I do not want the author of Foo's javascript file to have to know about MAGIC_LOOKUP_TABLE, but instead to merely annotate the method to be called.
I found the following example in the Function.name documentation
const o = {
foo(){}
};
o.foo.name; // "foo";
The problem in typescript (typed here):
const o: { foo: () => void } = {
foo: () => {
}
};
o.foo.name;
comes when I want to retrieve
o.foo.name, where I will get an error
TS2339 (property "name" does not exist)
How can I deal with it, keeping the object typing?
I want to avoid having to cast the property "foo" like (<any>o.foo).name
PS: The use case is to keep the typing for further refactoring. For instance the following is safe to be refactored:
spyOn(o, (<any>o.foo).name)
While this one is not
spyOn(o, "foo")
PS 2: It seems retrieving function name could be problematic on ts: Get name of function in typescript
The problem is that this code only works for newer versions of Javascript. If you change the target on the typescript compiler settings to es2015 the problem goes away. If you target es5 the definitions for that version do not include the name property because it might not work on older Javascript runtimes.
If you are ok with targeting es2015, that is ok, if not you should come up with a different solution that works for es5.
If you are targeting an environment that supports this property but you don't yet trust the es2015 implementation for all features, you could just add the the Function interface the missing property. At the top level in one of your files you can redefine the Function interface, and this will be merged into the default definition, adding the extra property:
interface Function {
/**
* Returns the name of the function. Function names are read-only and can not be changed.
*/
readonly name: string;
}
Post ES2015, this:
const o: { foo: () => void } = {
foo: () => { }
};
console.log(o.foo.name);
should work just fine.
Check it in the Typescript Playground, and observe the produced JavaScript. You will see the common sections with the foo example you mentioned.
Here is the console, nice and clean:
Pre-ES2015, this wouldn't work and I think you would have to cast it, if targeting post-ES2015 is not an option.
I want to create a global function that can be called anywhere in my other qml files. Have tried to put a function inside of a rectangle, but it gives me syntax error in the next object. I don't want to use singleton because the syntax would be like Singleton.foobar. I just want to use foobar at anywhere in other qml.
Rectangle {
function foobar(v) {
return v * 2;
}
}
ApplicationWindow { // syntax error here
}
Define the function in your root-node (ApplicationWindow).
This will be the last place, QML will look for a name, before it resorts to the C++-context properties.
See here to find out, how the names of variables and functions are resolved in QML.
It is not possible however to modify the global object, so true global JS-functions are not possible.
The more efficient approach however would be, to keep it always in one of the moste specific scopes, so referencing it with Identifyer.function() would be faster to look up. The singleton for libraries however is not the way to go. Look here for the usage of JS libraries.
Create C++ class with invokable function:
...
class MyCPPObject : public QObject
{
Q_OBJECT
public:
...
Q_INVOKABLE bool funToCallFromJS(int any, QString args);
...
Create MyCPPObject object in global space (rule is following: it must exist until engine exists (it's some simplification, but enough))
...
MyCPPObject cppobj;
...
Use following code to export it to qml and js:
...
QJSValue wrapobj = engine.newQObject(&cppobj);
engine.globalObject().setProperty("cppFun", wrapobj.property("funToCallFromJS"));
...
wrapobj also must exists while engine exists (again simplification)
4. In qml and JS:
...
if(cppFun(127, "abc"))
console.log("It works!");
...
Note: i used different names in qml space and cpp space just to show it's possible to rename cpp function when it used from js, but you can use same name, of course.
Is there a way to get PhpStorm intellisense to pick up these dynamically defined constants? Given the code below, PhpStorm gives the "Undefined constant SAMPLE_CONSTANT_THAT_WAS_DYNAMICALLY_DEFINED" error message.
class ExampleConfiguration
{
private $configurationMapping;
...
public function DefineConfigConstants()
{
foreach ($this->configurationMapping as $key => $value)
define($key, $value);
}
}
class ExampleClass
{
public function Test()
{
print SAMPLE_CONSTANT_THAT_WAS_DYNAMICALLY_DEFINED;
}
}
This issue can be tracked here: https://youtrack.jetbrains.com/issue/WI-11390, what I'm looking for is suggestions for workarounds.
IDE needs to know about such constants in order to not to complain about them. This means that they have to be defined in "normal" way (actual values do not matter, as long as they are not used for file names/paths in include/require statements).
Suggestion: write custom script that create such myconstants.php file where they will be defined in a normal way (since all such constants defined by users and stored in DB, you have to fetch them from DB yourself) .. and run this script (to update generated file) before working with the code in PhpStorm.
I am trying to understand how you return non-primitives (i.e. types that do not implement Copy). If you return something like a i32, then the function creates a new value in memory with a copy of the return value, so it can be used outside the scope of the function. But if you return a type that doesn't implement Copy, it does not do this, and you get ownership errors.
I have tried using Box to create values on the heap so that the caller can take ownership of the return value, but this doesn't seem to work either.
Perhaps I am approaching this in the wrong manner by using the same coding style that I use in C# or other languages, where functions return values, rather than passing in an object reference as a parameter and mutating it, so that you can easily indicate ownership in Rust.
The following code examples fails compilation. I believe the issue is only within the iterator closure, but I have included the entire function just in case I am not seeing something.
pub fn get_files(path: &Path) -> Vec<&Path> {
let contents = fs::walk_dir(path);
match contents {
Ok(c) => c.filter_map(|i| { match i {
Ok(d) => {
let val = d.path();
let p = val.as_path();
Some(p)
},
Err(_) => None } })
.collect(),
Err(e) => panic!("An error occurred getting files from {:?}: {}", pa
th, e)
}
}
The compiler gives the following error (I have removed all the line numbers and extraneous text):
error: `val` does not live long enough
let p = val.as_path();
^~~
in expansion of closure expansion
expansion site
reference must be valid for the anonymous lifetime #1 defined on the block...
...but borrowed value is only valid for the block suffix following statement
let val = d.path();
let p = val.as_path();
Some(p)
},
You return a value by... well returning it. However, your signature shows that you are trying to return a reference to a value. You can't do that when the object will be dropped at the end of the block because the reference would become invalid.
In your case, I'd probably write something like
#![feature(fs_walk)]
use std::fs;
use std::path::{Path, PathBuf};
fn get_files(path: &Path) -> Vec<PathBuf> {
let contents = fs::walk_dir(path).unwrap();
contents.filter_map(|i| {
i.ok().map(|p| p.path())
}).collect()
}
fn main() {
for f in get_files(Path::new("/etc")) {
println!("{:?}", f);
}
}
The main thing is that the function returns a Vec<PathBuf> — a collection of a type that owns the path, and are more than just references into someone else's memory.
In your code, you do let p = val.as_path(). Here, val is a PathBuf. Then you call as_path, which is defined as: fn as_path(&self) -> &Path. This means that given a reference to a PathBuf, you can get a reference to a Path that will live as long as the PathBuf will. However, you are trying to keep that reference around longer than vec will exist, as it will be dropped at the end of the iteration.
How do you return non-copyable types?
By value.
fn make() -> String { "Hello, World!".into() }
There is a disconnect between:
the language semantics
the implementation details
Semantically, returning by value is moving the object, not copying it. In Rust, any object is movable and, optionally, may also be Clonable (implement Clone) and Copyable (implement Clone and Copy).
That the implementation of copying or moving uses a memcpy under the hood is a detail that does not affect the semantics, only performance. Furthermore, this being an implementation detail means that it can be optimized away without affecting the semantics, which the optimizer will try very hard to do.
As for your particular code, you have a lifetime issue. You cannot return a reference to a value if said reference may outlive the value (for then, what would it reference?).
The simple fix is to return the value itself: Vec<PathBuf>. As mentioned, it will move the paths, not copy them.