I'm trying to return a type from a fortran function. This is the code.
module somemodule
implicit none
! define a simple type
type sometype
integer :: someint
end type sometype
! define an interface
interface
! define a function that returns the previously defined type
type(sometype) function somefunction()
end function somefunction
end interface
contains
end module somemodule
In gfortran (4.4 & 4.5) I get the following error:
Error: The type for function 'somefunction' at (1) is not accessible
I compiled the file as:
gfortran -c ./test.F90
I tried to make the type explicitly public but that didn't help. I was planning to use a c version of the somefunction, that is why I put it in the interface section.
Why is the type not accessible?
Adding import inside the function definition fixes this. Due to what many consider a mistake in the design of the language, definitions aren't inherited inside of an interface. The "import" overrides this to achieve the sensible behavior.
interface
! define a function that returns the previously defined type
type(sometype) function somefunction()
import
end function somefunction
end interface
The answer to the question why it is not accessible is that the standard committee designed it like that. The interface has a separate scope from the enclosing module, so you have to explicitly import names from it. Obviously(?) you can't use the module inside itself, so the import statement is needed.
Related
I am very new to Rust, and the :: operator is new to me. I can tell that :: and . both have their own use cases, and I want to understand on a conceptual level where/why code would use :: vs . or vice versa. Apologies if this is a really basic question!
:: is a path divider. It's mostly used for navigating submodules to express paths that lead to types, traits, modules and stand-alone functions (aka items):
// import everything in the collections module
use std::collections::*;
// specify a fully-qualified type without imports
let map = std::collections::HashMap::new();
// call a stand-alone function
let mut iter = std::iter::once(1);
. is used for navigating data. Specifically, that means accessing members of structs and calling methods:
// call a method
vec.sort();
// access a field of a struct
let bar = foo.bar;
. is really syntactic sugar for :: when talking about (structs, enums, traits):
A call to MyStruct::foo(&my_struct) would be evaluated from my_struct.foo().
You can mostly substitute them when working with what was mentioned above.
Also, :: is used as a "namespace" accessor, for navigatring through rust modules. For example for referring to a method in a nested submodule system:
std::collections::HashMap::get
As a note here, full submodule paths cannot be accessed in any other way with ..
Partially solved:
There is an old issue on github where this problem is described a bit. When you declare a module in a global scope, it rewrites the whole exported module's types. When you declare a module inside a module, it merges. Why? I have no idea
https://github.com/microsoft/TypeScript/issues/17736#issuecomment-344353174
I want to extend third party module's type by interface merging. Everything works fine, but when I comment
export {}; in types.d.ts I encounter the following error:
This expression is not callable. Type 'typeof import("koa-session")'
has no call signatures
Could you explain why it happens?
You can check the working code here:
https://codesandbox.io/s/typescript-node-nocfq?file=/src/types.d.ts
A similar problem has been addressed on TypeScript github. Unfortunately I am now aware of any other documentation page that would describe it.
Commenting out the export {} turns the types.d.ts file from a module into a script. From TypeScript handbook:
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
Since the file without export statement (and without import statement) is not a module but rather a script it has no information about any modules and will indeed disregard the fact that there is an existing definition for "koa-session".
You can try this in your sandbox - adding any top-level import or export in types.d.ts (it can be completely unused) will fix the This expression is not callable error.
You need to import the interface if you want to enhance it and do interface merging. What you're doing is rewriting it altogether.
import Session from "koa-session";
declare module "koa-session" {
interface Session {
user: {
id: number;
username: string;
};
}
}
Just do this and you will enhance the interface just as you want.
When I try to import node.js module in TypeScript like this:
import co = require('co');
import co from 'co';
without providing type definitions, both lines reports same error:
error TS2307: Cannot find module 'co'.
How to import it correctly?
The trick is to use purely JavaScript notation:
const co = require('co');
Your options are to either import it outside TypeScript's module system (by calling a module API like RequireJS or Node directly by hand) so that it doesn't try to validate it, or to add a type definition so that you can use the module system and have it validate correctly. You can stub the type definition though, so this can be very low effort.
Using Node (CommonJS) imports directly:
// Note there's no 'import' statement here.
var loadedModule: any = require('module-name');
// Now use your module however you'd like.
Using RequireJS directly:
define(["module-name"], function (loadedModule: any) {
// Use loadedModule however you'd like
});
Be aware that in either of these cases this may mix weirdly with using real normal TypeScript module imports in the same file (you can end up with two layers of module definition, especially on the RequireJS side, as TypeScript tries to manage modules you're also managing by hand). I'd recommend either using just this approach, or using real type definitions.
Stubbing type definitions:
Getting proper type definitions would be best, and if those are available or you have time to write them yourself you should definitely should.
If not though, you can just give your whole module the any type, and put your module into the module system without having to actually type it:
declare module 'module-name' {
export = <any> {};
}
This should allow you to import module-name and have TypeScript know what you're talking about. You'll still need to ensure that importing module-name does actually load it successfully at runtime with whatever module system you're using, or it will compile but then fail to actually run.
I got an error when I used the "Stubbing type definitions" approach in Tim Perry's answer: error TS2497: Module ''module-name'' resolves to a non-module entity and cannot be imported using this construct.
The solution was to rework the stub .d.ts file slightly:
declare module 'module-name' {
const x: any;
export = x;
}
And then you can import via:
import * as moduleName from 'module-name';
Creating your own stub file lowers the barrier to writing out real declarations as you need them.
Just import the module the following way:
import 'co';
I write module which will define new types. Inside newproperty definition I want to use custom function (also provided in this module) which will munge passed value:
Function
#lib/puppet/parser/functions/my_custom_function.rb
module Puppet::Parser::Functions
newfunction(:my_custom_function, :type => :rvalue) do |args|
...
end
end
Type
#lib/puppet/type/new_type.rb
Puppet::Type.newtype(:new_type) do
newparam(:name) do
munge do |value|
my_custom_function(value)
end
end
end
but I get undefined local variable or method when try use function in type like above.
I also don't have access to stdlib functions inside custom type, but these functions are available in manifest file.
Does someone can provide example how to execute custom function inside type definition especially in munge block?
Custom functions are parser functions, for use in your manifests only.
The type code is used by the agent only, which will not load parser functions while initializing resources.
You will have to duplicate your munging code. If this is not feasible, you may have to implement it in a custom Ruby library, and use that from both within your custom function and your type. The library will need to be installed on both masters and agents in this case.
You need to extract the code from your custom function into a separate location and then call that shared code from both your custom function and from your type/provider. You do not need to pull the code into a separate gem to do this, it is fairly easy to keep the code local to your module.
Put your own Ruby classes in the directory lib/puppet/util/ of your module. You should then be able to require 'puppet/util/my_class' from both your custom function and your type/provider. You can see an example of how I've done this in my module jboss-puppet_admin.
I would like to be able to use plain java-style implicit/explicit casting instead of asType overrides so that sources written in Java work properly. I've overridden asType on String similarly to the approach suggested in How to overload some Groovy Type conversion for avoiding try/catch of NumberFormatException? like:
oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = {Class typ ->
if (Foo.class.isAssignableFrom(typ)) {
Foo.myCast(delegate)
} else {
oldAsType.invoke(delegate,typ)
}
}
I'd like all of these options to work:
// groovy
String barString
Foo foo = barString asType(Foo.class) // asType works but
Foo foo = barString // implicit cast fails
Foo foo = (Foo) barString // explicit cast fails
The latter two fail because groovy is using DefaultTypeTransformation.castToType, which doesn't attempt to invoke new Foo() unless the object to be cast is either one of a slew of special cases or is some sort of Collection type.
Note that the solution Can I override cast operator in Groovy? doesn't solve the issue because the code that is doing the casting is regular Java code that I cannot alter, at least not at the source code level. I'm hoping that there is either a secret hook into casting or a way to override the static castToType method (in a Java class, called by another Java class - which Can you use Groovy meta programming to override a private method on a Java class says is unsupported)... or some other clever approach I haven't thought of.
Edit: The question is about using Java-style casting syntax, essentially to use groovy facilities to add an autoboxing method. Groovy calls this mechanism "casting," for better or worse (see DefaultTypeTransformation.castToType as referenced above). In particular, I have replaced an enum with a resourced class and want to retain JSON serialization. Groovy's JSON package automatically un/marshals enum values of instance members to strings and I'm trying to make the replacement class serialize compatibly with a minimal changes to the source code.
Part of the problem here is you are confusing conversion with casting. Using the "as" operator is not the same thing as imposing a cast. They seem similar, but they serve separate purposes.
Foo foo = (Foo) barString
That doesn't say something like "create a Foo out of barString". That says "Declare a reference named foo, associate the static type Foo with that reference and then point that reference at the object on the heap that the reference barString currently points to.". Unlike languages like C++, Groovy and Java do not allow you to ever get in a situation where a reference points at an object that is of a type that is incompatible with the reference's type. If you ever got into a situation where a Foo reference was pointing to a String on the heap, that would represent a bug in the JVM. It cannot be done. You can come up with ways to create Foo objects out of String objects, but that isn't what the code above is about.
The answer appears to be "no". Absent a rewrite of the DefaultTypeTransformation.castToType to allow for this sort of metaprogramming, the implication is to use another implementation strategy or use a different language.