I was wondering if I could import a header file, but not include any of that header file's included headers.
Suppose I have Class A that imports Class B. In Class B, I import Class C. Is there any way I can hide Class C from Class A?
No, you cannot do that: once you import a file, all its imports come in as well.
However, if you want to use only ClassA, you can forward-declare it in your own header, instead of importing ClassA's header:
#class ClassA;
Now you can make variables of type ClassA*, use ClassA* as return type or a parameter type, etc. At the same time, dependencies of ClassA's header will not be loaded.
In general, it is a good idea to reduce the number of headers that you import inside your header, for example by moving imports related to implementation (rather than the interface) into the .m file, and using class extensions.
Related
I was using some global methods in the /var directory of the shared library, and everything worked fine. Now I need to keep the state of the process, so I'm writting a groovy class.
Basically I have a class called 'ClassTest.groovy' in '/src' which is something like this;
class ClassTest {
String testString
def method1() { ... }
def method2() { ... }
}
and at the begining of the pipeline
library 'testlibrary#'
import ClassTest
with result:
WorkflowScript: 2: unable to resolve class ClassTest #line 2, column 1.
import ClassTest
before, I was just goind
library 'testlibrary#' _
and using the methods as
script {
libraryTest.method1()
...
libraryTest.method2()
}
where the methods were in a file '/var/libraryTest.groovy' and everything worked. So I know that the shared library is there, but I'm confused with the way groovy / Jenkins handle classes / shared libraries.
What's the correct way to import a class? I cannot find a simple example (with groovy file, file structure and pipeline) in the documentation.
EDIT:
I moved the file to 'src/com/company/ClassTest.groovy' and modified the pipeline as
#Library('testlibrary#') import com.company.ClassTest
def notification = new ClassTest()
but now the error is
unexpected token: package # line 2
the first two lines of the groovy file are:
// src/com/company/ClassTest.groovy
package com.company;
So far this is what I've found.
To load the library in the pipeline I used:
#Library('testlibrary#') import com.company.ClassTest
def notification = new ClassTest()
In the class file, no package instruction. I guess that I don't need one because I don't have any other files or classes, so I don't really need a package. Also, I got an error when using the same name for the class and for the file where the class is. The error specifically complained and asked for one of them to be changed. I guess this two things are related to Jenkins.
That works, and the library is loaded.
(Maybe it can help someone else)
I was having the same issue.
Once I added a package-info.java inside the folder com/lib/, containing
/**
* com.lib package
*/
package com.lib;
and adding package com.lib at the first line of each file, it started to work.
I had the same problem.
After some trial and error with the docs of Jenkins.(https://www.jenkins.io/doc/book/pipeline/shared-libraries/#using-libraries)
I found that when I wanted to import a class from the shared library I have, I needed to do it like this:
//thanks to '_', the classes are imported automatically.
// MUST have the '#' at the beginning, other wise it will not work.
#Library('my-shared-library#BRANCH') _
// only by calling them you can tell if they exist or not.
def exampleObject = new example.GlobalVars()
// then call methods or attributes from the class.
exampleObject.runExample()
I'd like to make scalastyle to ignore underscore imports in case when it is companion object's fields that are being imported(it makes sense to me):
class Item {
import Item._ //scalastyle marks it as a warning
}
object Item {
case object Nested
def someMethod(): Unit = {..}
}
UnderscoreImportChecker is responsible for this inspection, but it has no configuration parameters
<check level="warning" class="org.scalastyle.scalariform.UnderscoreImportChecker" enabled="true"></check>
Here is the similar question:
Companion class requires import of Companion object methods and nested objects?
I'd like to ask if there is a way to write a custom Checker(I'll try to investigate it)?
P.S. I'm aware that I can use //scalastyle:off or explicit imports but it would be repetitive and inconvenient to use.
I'm trying to simply use types (interfaces) from other commonjs modules. I'm wondering if there is a way to do this without having to import the module each time I need just the types (no implementation)?
Also to the same point. How would I use commonjs declared module types in projects without compiling with "--module commonjs"? (just to use the types, I'm aware you could do var x = require('x') if you don't care about type safety, but that defeats the purpose of TypeScript)
This seems like a valid use case as one could desire to create a library free from the actual implementation... But as I currently see it, you have to import x = require('x') on the actual implementation, even if I don't need it and already have the definition file.
Is there a way to tell the compiler that it "just exists," similar to how declare works with variables?
Example:
Suppose I have file.ts that I'm not compiling with any module setting (none):
/// <reference path="ExternalCommonJSModule.d.ts" />
export class A {
public foo(bar: ITypeFromExternalCommonJSModule): number {
return bar.x * 2;
}
}
And suppose ExternalCommonJSModule.d.ts looks like this:
declare module "ExternalCommonJSModule" {
export interface ITypeFromExternalCommonJSModule {
x: number;
}
}
(note, this doesn't compile because file.ts isn't compiled with --module commonjs and it doesn't import the implementation of the .d.ts)
I'm wondering if there is a way to do this without having to import the module each time I need just the types (no implementation)
You can put the interfaces in a global module e.g. globals.d.ts and then you would be able to use them throughout the project without importing.
Note: as soon as you global you are severely limiting the shareability of your code and opening yourself to the diamond version dependency problem.
As far as I can tell from the website, the following code should compile to a DLL with a top-level property Version:
namespace MyLibrary
[Module]
class MainClass:
public static Version as string
static def constructor():
Version = "0.1"
This compiles, but if I then enter these commands into booish:
import MyLibrary
print (Version)
then I get "ERROR: Unknown identifier: 'Version'".
Presumably this code worked in an earlier version of the language. I am using 0.9.4.9. What is the correct way to achieve this effect?
(I've noticed that there is an implicit static class MyVersionModule in which top-level static methods get placed, but I don't know how to add properties to this either).
In .net there is no way to have methods or fields that are not actually members of a class. Boo hides this somewhat by having the implicit class for the main file in the module (as you noticed) but when importing you still need to access it as a member.
For statics you have to first reference the type then the member so in your example printing the version would be like this:
import MyLibrary
print (MainClass.Version)
Of course this isn't the 'correct' way to store version information in .net though, which is to use assembly level attributes instead. That would look more like this:
[assembly: System.Reflection.AssemblyVersion("1.0")]
namespace MyLibrary
[Module]
class MainClass:
pass
Then getting the version you would do using reflection, there are a couple of ways to get the assembly but the easiest is to get the Type then it's assembly:
import System
import System.Reflection
import MyLibrary
atts = typeof(MainClass).Assembly \
.GetCustomAttributes(typeof(AssemblyVersionAttribute), false)
version = (atts[0] as AssemblyVersionAttribute).Version
print(version)
If I have four .h/.m file pairs
file1.h
file2.h
file3.h
file4.h
where I am using file1.h, file2.h, and file3.h functionality in file4, should those header files be included in file4.h or file4.m?
In the .m file if possible. You may have to forward declare classes in the .h file, like:
#class AClassIImportInDotMFile;
If Class B is a subclass of Class A, you need to import Class A's .h file in Class B's .h file.
I assume file4.h is going to be used by other .m files. If so, only include in file4.h what is used in file4.h, and the rest in file4.cpp. This will reduce the overal number of inclusions and including file4.h will not pull useless additional headers.
When the number of required .h files starts to grow inconveniently, you can group them in topic headers. For instance, topic1.h may include file1.h and file2.h but not file3.h.
I Usually import the other headers into the current header file if I plan on using their classes in property declaration. However this can create some havoc if the classes reference each other.
If this is the case then you will want to include the headers in the .m file so they can be used inside the class, but for any external access to these items you would use id in the place of your custom classes. And cast them when you get them in the other referencing methods.
I run into this issue if I include the AppDelegate.h and then reference the other class in app delegate.
the reason for this would be that I want to include a reference to my current object in the app delegate, but the class also uses the app delegate to access other classes. In this case I would include the Classes in the AppDelegate.h and include AppDelegate.h in the m file of the class.
I hope that made sense.