How do I include one .zig file from another .zig file - zig

Just exploring Zig... I have one .zig file with a bunch of comptime functions and constants, and I want to use those in other .zig programs. Equivalent to #include "my.h" in C.

The answer is that #import("foo.zig") almost does this. If you had foo.zig:
const a = 1;
pub const b = 2;
pub const c = 3;
then in main.zig:
const stdout = #import("std").io.getStdOut().writer();
const foo = #import("foo.zig");
const c = foo.c;
const a = foo.a;
test "#import" {
// try stdout.print("a={}\n",.{foo.a});
// try stdout.print("a={}\n",.{a});
try stdout.print("b={}\n",.{foo.b});
try stdout.print("c={}\n",.{c});
}
will print the values of b and c but if you uncomment the commented lines, you'll get an error because a wasn't exported (pub). Interestingly the const a=foo.a doesn't give an error unless a is used.
It appears that there is no way to dump all of an import into the current namespace, so if you want the names unqualified, you have to have a const line for each.
Thanks to people in the Zig discord, particularly #rimuspp and #kristoff

You actually can use:
const bar = struct {
usingnamespace #import("foo.zig");
};
to import a complete namespace into a struct, but not at the top level.

Related

Google Sheet script: PASTE_CONDITIONAL_FORMATTING option not working with copyTo method

I am trying to copy conditional formatting from a GS range to another range and nothing is copied (no error). This is the snippet:
spreadsheet.getSheetByName('sheet_source').getRange(14,7,200,19).copyTo(spreadsheet.getSheetByName('sheet_target').getRange(14,7,200,19), SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING, false);
If I use the same code but change the CopyPasteType to a different option, it works (see example below). The problem is that I only want conditional formatting copied so I need the PASTE_CONDITIONAL_FORMATTING to work. Please let me know if you have any suggestions.
spreadsheet.getSheetByName('sheet_source').getRange(14,7,200,19).copyTo(spreadsheet.getSheetByName('sheet_target').getRange(14,7,200,19), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
Per doubleunary's suggestion, I reformatted the script as follows, and it works:
function CndFmtFromTmplt_PasteCndFmt() {
//get spreadsheet
const spreadsheet = SpreadsheetApp.getActive();
//get sheets
const sheetSource = spreadsheet.getSheetByName("Template");
const sheetTarget = spreadsheet.getSheetByName("Test Sheet");
//clear rules
sheetTarget.clearConditionalFormatRules();
//get copy ranges
//const rangeSource = sheetSource.getRange(1, 1, sheetSource.getMaxRows(), sheetSource.getMaxColumns());
const rangeSource = sheetSource.getRange('A1:AF200');
const rangeTarget = sheetTarget.getRange('A1:AF200');
// copy values to destination range
rangeSource.copyTo(rangeTarget, SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING,false);
};
The code you show looks fine, so it is unclear where the problem is. To make debugging easier, try structuring your code a bit, like this:
function test() {
const ss = SpreadsheetApp.getActive();
const sourceRange = ss.getRange('sheet_source!N7:S200');
const targetRange = ss.getRange('sheet_target!N7');
sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING, false);
}
Check My Executions for failed executions, and view those logs to learn more about why the function fails. You can run the test() function in the script editor when testing.

How can I disable requiring types for collection literals in Dart?

I'm currently using the pedantic package for my dart/flutter linting.
My analysis_options.yaml look like
include: package:pedantic/analysis_options.yaml
linter:
rules:
always_specify_types: true
omit_local_variable_types: false
I like having to specify types when I declare a variable line. But with this, I have to also specify the type on the created list/map.
The issues I have are the parts within **
const int number = 5;
const bool isTrue = false;
const String myName = 'Dan';
const List<int> numbers = **<int>**[1, 2, 3, 4];
const Map<String, int> ages = **<String, int>**{'Dan': 1};
It's redundent. How can I set my analysis_options.yaml to fix this.
Thanks!

When is const optional in Dart 2?

In Dart Object() constructor is declared as const so:
identical(const Object(), const Object()); //true
I know that in Dart 2 the keyword const is optional and I thought that the previous statement was equivalent to:
identical(Object(), Object()); //false
But actually it seems to be equivalent to:
identical(new Object(), new Object()); //false
Now my doubts are:
1) When is const keyword optional?
2) Is there any way to ensure instances of my classes to be always constant without const keyword? So that I can obtain:
indentical(MyClass(), MyClass()); //true (is it possible?)
Dart 2 allows you to omit new everywhere. Anywhere you used to write new, you can now omit it.
Dart 2 also allows you to omit const in positions where it's implied by the context. Those positions are:
Inside a const object creations, map or list literal (const [1, [2, 3]]).
Inside a const object creation in metadata (#Foo(Bar()))
In the initializer expression of a const variable (const x = [1];).
In a switch case expression (case Foo(2):...).
There are two other locations where the language requires constant expressions, but which are not automatically made constant (for various reasons):
Optional parameter default values
initializer expressions of final fields in classes with const constructors
1 is not made const because we want to keep the option of making those expressions not need to be const in the future. 2 is because it's a non-local constraint - there is nothing around the expression that signifies that it must be const, so it's too easy to, e.g., remove the const from the constructor without noticing that it changes the behavior of the field initializer.
const is optional in a const context. Basically a const context is created when the expression has to be const to avoid compilation error.
In the following snippet you can see some place where const is optional:
class A {
const A(o);
}
main(){
// parameters of const constructors have to be const
var a = const A(const A());
var a = const A(A());
// using const to create local variable
const b = const A();
const b = A();
// elements of const lists have to be const
var c = const [const A()];
var c = const [A()];
// elements of const maps have to be const
var d = const {'a': const A()};
var d = const {'a': A()};
}
// metadatas are const
#A(const A())
#A(A())
class B {}
You can find more details in Optional new/const and Implicit Creation.

Accessing <objc/runtime.h> from Cycript

I wan't to be able to use associated objects and ISA swizzle, but I can't figure out how to import objc/runtime.h for use with Cycript. I have tried in both the console and in .js files but no luck.
Ideally I'd like to figure out how to include frameworks as well.
It seems like a subset of runtime.h is included by default in the Cycript environment. For example, class_copyMethodList and objc_getClass work without any added effort.
var count = new new Type(#encode(int));
var methods = class_copyMethodList(objc_getClass("NSObject"), count);
However objc_setAssociatedObject is not referenced:
objc_getAssociatedObject(someVar, "asdf")
#ReferenceError: Can't find variable: objc_getAssociatedObject
After a lot of searching, I realized the answer was right under my nose. limneos's weak_classdump uses the runtime to do it's dump and Cycript's tutorial shows how to grab C functions.
The solution I ended up with is this:
function setAssociatedObject(someObject, someValue, constVoidPointer) {
SetAssociatedObject = #encode(void(id, const void*, id, unsigned long))(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"))
SetAssociatedObject(someObject, constVoidPointer, someValue, 1)
}
function getAssociatedObject(someObject, constVoidPointer) {
GetAssociatedObject = #encode(id(id, const void*))(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"))
return GetAssociatedObject(someObject, constVoidPointer)
}
It is used like this:
# create void pointer (probably should be a global variable for later retrieval)
voidPtr = new new Type(#encode(const void))
someVar = [[NSObject alloc] init]
setAssociatedObject(someVar, #[#"hello", #"world"], voidPtr)
getAssociatedObject(someVar, voidPtr)
# spits out #["Hello", "World"]

Lua package containing subpackages

I have written a number of modules for Lua in C. Each of these contains a Lua userdata type and I load and use them like this:
A = require("A")
B = require("B")
a = A.new(3,{1,2,3})
b1 = B.new(1)
b2 = B.new(2) * b1
Now I would like to put both userdata types in a single shared library AandB that can be used like this
AB = require("AandB")
AB.A.new(3,{1,2,3})
What is a good way to achieve this? Right now my luaopen_* functions look like this
int luaopen_A(lua_State *L) {
luaL_newmetatable(L, A_MT);
luaL_setfuncs(L, A_methods, 0);
luaL_newlib(L, A_functions);
return 1;
};
And is it possible then to still load only part, e.g. like this: A = require("AandB.A")?
require("AandB.A") works if you define luaopen_AandB_A in your C library, which must be called AandB.so.
In general, require replaces dots with underscores when trying C libraries.
One thing you can do is to write a lua script module that pulls in both A and B. You can then require that script from your using code:
-- AandB.lua
return { A = require 'A', B = require 'B' }
If you only want to load part of your module, you can just do:
A = require "AandB".A

Resources