I'm fairly new with OCaml Module and I haven't managed to use my own module without combining both an "include" and an "open".
I've tried to put the signature in a separate .mli file, without success.
Below I'm indicated a minimum (not) working example, that I'm trying to compile with
ocamlc -o main Robot.ml main.ml
What to I need to do to only have to use "open", or only "include", but not both of them ?
File "Robot.ml" :
module type RobotSignature =
sig
val top: unit -> unit
end
module Robot =
struct
let top () =
begin
Printf.printf "top\n"
end
(* Should not be visible from the 'main' *)
let dummy () =
begin
Printf.printf "dummy\n"
end
end
File "main.ml" (not working) :
open Robot;;
top();
File "main.ml" (working) :
include Robot;;
open Robot;;
top();
You've got two levels of Robot. Since you explicitly called your module "Robot" within the file robot.ml you'll need to open Robot and then call Robot.top(). Anything in the robot.ml file is already put implicitly inside of a Robot module.
You could get rid of the extra 'module Robot' declaration in robot.ml.
robot.ml would become:
module type RobotSignature =
sig
val top: unit -> unit
end
let top () =
begin
Printf.printf "top\n"
end
Then it should work as you have it in your main.ml.
Update based on comment below: If you're concerned that everything in robot.ml will now be visible when you 'open Robot' you can define a robot.mli file which specifies the functions which are available externally. For example, let's say you add a function called helper in robot.ml:
let top () =
begin
Printf.printf "top\n"
end
let helper () =
Printf.printf "helper\n"
...and then you define your robot.mli as follows:
val top: unit -> unit
Then let's say you try to call helper from main.ml:
open Robot;;
top();
(* helper will not be visible here and you'll get a compile error*)
helper ()
Then when you try to compile you'll get an error:
$ ocamlc -o main robot.mli robot.ml main.ml
File "main.ml", line 4, characters 0-6:
Error: Unbound value helper
You have two ways to do this:
First, you can constrain your sub-structure to be of the right signature:
module Robot : RobotSignature = struct ... end
Then in main.ml, you can do open Robot.Robot: the first Robot means the compilation unit associated to robot.ml, the second Robot is the submodule you have defined inside robot.ml
You can also remove one level and create robot.mli containing:
val top: unit -> unit
and robot.ml containing:
let top () =
Printf.printf "top\n"
(* Should not be visible from the 'main' *)
let dummy () =
Printf.printf "dummy\n"
You can compile the modules using ocamlc -c robot.mli && ocamlc -c robot.ml and then in main.ml simply use open Robot.
Related
I'm trying to use a function that is inside a file (module 1) in another file (module) 2. But it gives me an error "ERROR: UndefVarError: t1 not defined". I have tried to export the function in module 1 but it also doesn't work. I'm new to Julia and I do not know very well how to handle modules.
Here is the code that I'm having problems.
First File: t1.jl
module A
function soma(a::Int64, b::Int64)
return a + b
end
end
Second File: t2.jl
module B
include("t1.jl")
using .t1
function main()
s = soma(2, 3)
println(s)
end
main()
end
Changing t2.jl to:
module B
include("t1.jl")
using .A
function main()
s = A.soma(2, 3)
println(s)
end
main()
end
prints out 5 as expected.
include is basically as if you'd copy-pasted the code from the included file into the current file - so, once you've included t1.jl into module B, the fact that the file is called t1.jl has no relevance. It's module A that's in the current scope, and A is the namespace that contains the soma function we need. Hence, using .A is what's needed to make soma available within B.
A plugin defines a function named HLMarks():
hi Marks term=reverse ctermfg=0 ctermbg=40 guibg=Grey40
function! HLMarks(group)
call clearmatches()
let index = char2nr('a')
while index < char2nr('z')
call matchadd( a:group, '\%'.line( "'".nr2char(index)).'l')
let index = index + 1
endwhile
endfunction
I want the HLMarks() function to run automatically every time vim opens a file.
It works when I call the function manually:
:call HLMarks("Marks")
Adding this line to the end of the plugin didn't do anything:
call HLMarks("Marks")
Calling the function from vimrc got this error:
E117: Unknown function: HLMarks
How to automatically call the HLMarks("Marks") function when a file is opened?
The plugin is described on http://www.vim.org/scripts/script.php?script_id=3394
and down loaded from http://www.vim.org/scripts/download_script.php?src_id=21611
The plugin's markHL.vim file is in my ~/.vim/plugin/ directory.
The ":function" command lists:
function HLMarks(group)
The solution is to add this line to vimrc:
autocmd BufReadPost * call HLMarks("Marks")
Details are at https://groups.google.com/forum/#!topic/vim_use/i2HWD_9V-28
If you define the function in .vimrc then:
function! yourFunc()
" ...
endfunction
call yourFunc()
simply adding the call yourFunc() after the definition will work.
Am just starting out with Livescript and want to know how the scope works.
Are the any good example/docs that show all scope symbols and usage.
Symbols like:
#
-> vs ~>
self
:=
Edit
The problem I face:
This ethercalc code: line 103.
I want to insert a call to a Java script function, i.e. to this send email code.
http://livescript.net documents all that functionality.
# means this.
#prop means this.prop
-> creates a function, it means function(){}
-> blah() is function(){ return blah(); }
(a, b) -> foo is function(a, b) { return foo; }
self is nothing special, just the name of a variable. Often set to this of an upper scope.
:= means "reassign a variable" - it must already exist. It does not create a new variable.
Check out http://livescript.net/#introduction for more info
Is there a way to get the command line arguments in go "tests",
When you call go test obviously your main is not run, so is there a way to process command line arguments,
One way would be to use the flags packages and check for the command line arguments in each test or function being tested, but that is not ideal for that you need to do this in lots and lots of places, unlike the way you to it just in main when you run the application.
One may think it is a wrong thing to do, and that it is against purity of unit-tests:
not all tests are unit tests
it is very functional not to rely on "ENV" variables and actually pass the stuff as arguments in command line,
For the record I ended up putting an init() function in one of my _test files, and set the variable that is set through flags when the main is called this way.
Environmental configs are best kept in environment variables, in my experience. You can rely on global variables like so:
var envSetting = os.Getenv("TEST_ENV")
Alternatively, if using flags is a requirement, you could place your initialization code inside a function called init().
func init() {
flags.Parse()
myEnv = *envFlag
// ...
}
An alternative approach is to make main() be a stub that merely calls into another function after arguments are processed by flag.Parse(), for example:
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help for flagname")
}
func main() {
flag.Parse()
submain(flag.Args)
}
func submain(args []string) {
...
}
Then in your tests, flag variables can be set and arguments established before calling submain(...) simulating the command line establishment of flags and arguments. This approach can be used to maximize test coverage without actually using a command line. For example, in main_test.go, you might write:
func TestSomething(t *testing.T) {
flagvar = 23
args := []string{"a", "b", "c"}
submain(args)
...
}
You can directly test main function and pass arguments.
Simple example showing a flag, and a pair of positional arguments
Note: Do NOT call it 'TestMain' that has a special meaning to the testing framework as of Go 1.8.
package main
import (
"os"
"testing"
)
func TestMainFunc(t *testing.T) {
os.Args = append(os.Args, "--addr=http://b.com:566/something.avsc")
os.Args = append(os.Args, "Get")
os.Args = append(os.Args, `./some/resource/fred`)
main()
// Test results here, and decide pass/fail.
}
os.Args[1] = "-conf=my.conf"
flag.Parse()
Notice that the config file name is hard-coded.
I use value-parameterized tests in gtest. For example, if I write
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
::testing::Values("meeny", "miny", "moe"));
then in the output I see test names such as
InstantiationName/FooTest.DoesBlah/0 for "meeny"
InstantiationName/FooTest.DoesBlah/1 for "miny"
InstantiationName/FooTest.DoesBlah/2 for "moe"
Is there any way to make these names more meaningful? I'd like to see
InstantiationName/FooTest.DoesBlah/meeny
InstantiationName/FooTest.DoesBlah/miny
InstantiationName/FooTest.DoesBlah/moe
INSTANTIATE_TEST_CASE_P accepts an optional 4th argument which can be used for this purpose. See https://github.com/google/googletest/blob/fbef0711cfce7b8f149aac773d30ae48ce3e166c/googletest/include/gtest/gtest-param-test.h#L444.
This is now available in INSTANTIATE_TEST_SUITE_P.
The optional last argument to INSTANTIATE_TEST_SUITE_P() allows the
user to specify a function or functor that generates custom test name
suffixes based on the test parameters.
Of interest is also this section in the source:
// A user can teach this function how to print a class type T by
// defining either operator<<() or PrintTo() in the namespace that
// defines T. More specifically, the FIRST defined function in the
// following list will be used (assuming T is defined in namespace
// foo):
//
// 1. foo::PrintTo(const T&, ostream*)
// 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace.
Two ways: (http://osdir.com/ml/googletestframework/2011-09/msg00005.html)
1) Patch the existing PrettyUnitTestPrinter to print test names; something like:
--- a/gtest-1.7.0/src/gtest.cc
+++ b/gtest-1.7.0/src/gtest.cc
## -2774,6 +2774,7 ## void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_info.test_case_name(), test_info.name());
+ PrintFullTestCommentIfPresent(test_info);
printf("\n");
fflush(stdout);
}
2) Write a new TestListener to print test results however you like. (https://code.google.com/p/googletest/source/browse/trunk/samples/sample9_unittest.cc) GTest allows registering a new test listener (and un-registering the builtin default), allowing pretty flexible customization of test output. See the link for example code.