Is there a way to access functions through inheritance without setting function access to public?
For example: I have Foo.cfc and it extends Bar.cfc. If I want to call a Bar.cfc function from Foo.cfc, I have to set the function access to public.
If I set the function access to private, then it's only accessible from Foo.cfc. Is there no "intermediate" access level that is not quite public but not strictly private? i.e. it allows access through inheritance only...
Are you using the keyword super? Because private methods should be available to sub components like Foo.cfc.
Foo.cfc
<cfcomponent extends="Bar">
.....
<cffunction name="fooMethod" access="public" ...>
<cfreturn super.nameOfAMethodInBarCFC() />
</cffunction>
</cfcomponent>
If I set the function access to private, then it's only accessible from Foo.cfc
NOT TRUE! private access level in ColdFusion is same as protected in Java, so you can still call that private method of Bar from Foo
You need to set the access property in cffunction to package. That will allow it to be accessed by any component that extends the component.
Related
I am trying to invoke a private method in my unit test to initialize a value. I know I can use java reflections to invoke private methods, but I am wondering if I can use Apache MethodUtils to invoke a private method:
org.apache.commons.lang3.reflect.MethodUtils
Any suggestion would be much appreciated.
Private methods can be invoked using forceAccess = true:
MethodUtils.invokeMethod(ObjectName, true, "MethodName");
Somewhere I have read that private methods aren't supposed to be tested. Your tests should only care about the real thing - your public API. If your public methods work, then the private ones they call will also work
So is it not necessary to test private methods, but consider below example
private
def valid_extension?(file_path)
extension = file_type(file_path)
extension.in?(%w(csv xls xlsx)) ? true : false
end
the above private method returns whether the file extension is valid or not, so what if someone changes my private method like this
private
def valid_extension?(file_path)
true
end
it will always give me valid extension
So, is it not necessary to test private methods also.
Since we cannot access private method outside class, so how to test the private methods using rspec-rails.
As per Rspec, Rails: how to test private methods of controllers? , you may use
#your_instance_name.instance_eval{ valid_extension }
I want to create a LinkedinApi class, containing functions which execute web service requests to Linkedin servers. These functions need to be accessible from anywhere in the Play app code. The easiest way I've written such API classes in the past, was to have them declared as an object. Then LinkedinApi.myPublicFunction() is available from anywhere.
The problem is that I don't see how I can declare my LinkedinApi class as an object. It would use Play 2.4's web services, and this is done by adding #Inject()(ws: WSClient) to the class declaration. Something like object LinkedinApi #Inject()(ws: WSClient) extends Controller.
The problem is that the line above doesn't compile. It seems that #Inject can only be used with class declarations, not with object.
So how can I create application-wide API functions which perform web service calls?
I think you should define your LinkedinApi as a service and inject it where needed:
#Singleton
class LinkedinApi #Inject()(ws: WSClient) {
//...
//linkedin stuff
//...
}
and inject as:
#Singleton
class SomeController #Inject()(linkedinApi:LinkedinApi) {
//...
}
Is there a way to explicitly reference the THIS scope defined in Application.cfc?
Say I have an Application.cfc like this:
component {
this.name="MyApplication"
..
I know that from any page in the site, you can access this.name this way...
<cfoutput>#this.name#</cfoutput>
...but if you are in another component, how would you reach the Application.cfc's "this" scope? Is it possible without handing the var off?
Adobe documentation says that you can reference the "THIS" scope by using the instance or object name as a prefix. I tried Application.this.name but it didn't work.
Most of the things that are set in "this" in Application.cfc are not accessible outside the execution of it. ColdFusion copies this.name into application.name at runtime, so you can access application.name from anywhere in your application. For the other settings in "this", they appear to be accessible from your pages because the pages are included into the application.cfc execution cycle by the OnRequest() method.
Once you instantiate a CFC and work inside it's methods, the context of "this" changes to the constructor of that CFC.
Heres the situation. Component B extends component A and overrides the init method to accept a different parameter. A also has a create method that calls init.
If i have an instance of B and i call create, its calling the wrong init - it calls init in B, where i need it to call init in A.
I dont want to call super.init() as there may not always be a super. Is there any way to specify to call the init in the parent component?
Refactor the actual code you want to execute into their own methods, and have the Init methods call that code, and have the create method call that code as well.
It sounds like your objects are not well designed at the moment. Try to break your methods down to smaller, more constrained units.
Edit:
I think my answer still stands.
If the Init method in the parent component does some stuff, move that stuff to a new method, say, "initDoStuff(), and have the init method call that method.
Then, have your create method call the initDoStuff() method instead of init.
ColdFusion is a dynamically typed language, and you don't need to override methods just to accept different parameters. You can do that in other ways.
CF isn't able to pick methods based on argument signatures. So, if you have a situation like this, you need to handle it in a different way.
Basically, the idea of overriding a method to change its argument types is not really valid in ColdFuion.
Component A:
<cffunction name="init" access="public" output="false">
<cfargument name=... ...>
<cfreturn initDoSomething(argumentCollection=arguments)>
</cffunction>
<cffunction name="initDoSomething" access="package" output="false">
{do stuff}
<cfreturn {whatever}>
</cffunction>
Component B:
<cffunction name="create" access="package" output="false">
<cfset {something} = initDoSomething({whatever arguments})>
<cfreturn {whatever}>
</cffunction>
call the base initializer I don't know what language you're running but in C# it's for example B b = new B() : base(parameters...) of course you'd still have to check wether the component is in fact of type A or B but you can do that in most languages.
This will also run the extened initializer, but thats the way it is. If you want to get rid of the extended objects initializer you'll just have to create a parent type object I think. It's the only thing I can think of.
But of course it would help if you specified what language you are programming in, in order to know the options and syntax.
I solved this by extending the create method to call super.create and super.init. theres still a call to the child init that fails, but overall it works.
I would still prefer a solution that works on the parent init without having to override the create.