Check if class has static method - objective-c

We can easily check if object has a method by using respondsToSelector:, but how we do it for static functions in class?
I would like to have something like this:
if ([cls classRespondsToSelector:#selector(staticMethodName)]) {
...
}

In Objective-C classes are objects too.
if ([[myClass class] respondsToSelector:#selector(classMethod)]) {
}
Also a small note, these are NOT 'static' methods. That means something specific which doesn't exist in Objective-C. They are class methods.

Related

Calling a function from one kotlin class in another

I'm relatively new to Kotlin, however I studied Java before this. One thing I don't understand very well is calling a method/function from a class in another class.
Currently I have:
Class Commands(){
fun cmdInit(){
//code in here
}
}
Class Main(){
Commands.cmdInit() //This is how I would usually do it in java, however there is no static referencing in Kotlin, and I dont understand Object Declaration very well
}
Thanks in advance for helping. :D
If you want to acess it like a static method in Java, you can create a companion object. You just have to change your Commands class to this:
class Commands {
companion object {
fun cmdInit(){
//code in here
}
}
}
for more info: https://kotlinlang.org/docs/object-declarations.html#companion-objects

Testing private methods in Raku

Is there a way to test private methods in Raku?
I understand that one should ideally define their tests targeting the public methods, but is there a way to do it "the wrong way"? :)
I initially thought about defining a subclass for the Testing that inherited from the class I wanted to test and do the tests there, but it seems that private methods are not inherited.
Then I saw the 'trusts' routine, but I wouldn't want to reference a Testing class on any of the classes of the code.
Is there something like changing the 'private' property of a method via introspection?
What would be the best way to call/test a private method?
This can be done using introspection.
Consider this is the class you want to test:
class SomeClass {
has Int $!attribute;
method set-value(Int $value) returns Nil {
$!attribute = $value;
return;
}
method get-value returns Int {
return $!attribute;
}
# Private method
method !increase-value-by(Int $extra) returns Nil {
$!attribute += $extra;
return;
}
}
You may create a test like this:
use Test;
use SomeClass;
plan 3;
my SomeClass $some-class = SomeClass.new;
my Method:D $increase-value = $some-class.^find_private_method: 'increase-value-by';
$some-class.set-value: 1;
$increase-value($some-class, 4);
is $some-class.get-value, 5, '1+4 = 5';
$increase-value($some-class, 5);
is $some-class.get-value, 10, '5+5 = 10';
my SomeClass $a-new-class = SomeClass.new;
$a-new-class.set-value: 0;
$increase-value($a-new-class, -1);
is $a-new-class.get-value, -1, '0+(-1) = -1; The method can be used on a new class';
done-testing;
You first create an instance of the class and the use ^find_private_method to get its private Method. Then you can call that Method by passing an instance of a class as the first parameter.
There's a more complete explanation on this answer:
How do you access private methods or attributes from outside the type they belong to?
A fresh cup of tea and #Julio's and #JJ's answers inspired the following:
class SomeClass { method !private ($foo) { say $foo } }
use MONKEY-TYPING; augment class SomeClass { trusts GLOBAL }
my SomeClass $some-class = SomeClass.new;
$some-class!SomeClass::private(42); # 42
My solution tweaks the class using monkey typing. Monkey typing is a generally dodgy thing to do (hence the LOUD pragma). But it seems tailor made for a case just like this. Augment the class with a trusts GLOBAL and Bob's your Uncle.
Raku requires the SomeClass:: qualification for this to work. (Perhaps when RakuAST macros arrive there'll be a tidy way to get around that.) My inclination is to think that having to write a class qualification is OK, and the above solution is much better than the following, but YMMV...
Perhaps, instead:
use MONKEY-TYPING;
augment class SomeClass {
multi method FALLBACK ($name where .starts-with('!!!'), |args) {
.(self, |args) with $?CLASS.^find_private_method: $name.substr: 3
}
}
and then:
$some-class.'!!!private'(42); # 42
I've used:
A multi for the FALLBACK, and have required that the method name string starts with !!!;
A regular method call (. not !);
Calling the method by a string version of its name.
The multi and !!! is in case the class being tested already has one or more FALLBACK methods declared.
A convention of prepending !!! seems more or less guaranteed to ensure that the testing code will never interfere with how the class is supposed to work. (In particular, if there were some call to a private method that didn't exist, and there was existing FALLBACK handling, it would handle that case without this monkey FALLBACK getting involved.)
It should also alert anyone reading the test code that something odd is going on, in the incredibly unlikely case that something weird did start happening, either because I'm missing something that I just can't see, or because some FALLBACK code within a class just so happened to use the same convention.
Besides using introspection, you can try and use a external helper role to access all private methods and call them directly. For instance:
role Privateer {
method test-private-method ( $method-name, |c ) {
self!"$method-name"(|c);
}
}
class Privateed does Privateer {
method !private() { return "⌣" }
}
my $obj = Privateed.new;
say $obj.test-private-method( "private" );
The key here is to call a method by name, which you can do with public and private methods, although for private methods you need to use their special syntax self!.

Refer to nested objects without full qualification

I have code (all of which I control) that looks like the following:
class FirstVeryLongName {
object ObjectA
object ObjectB
object ObjectC
}
class SecondVeryLongName {
object ObjectB
object ObjectD
}
The code I need to write is equivalent to
operation1(FirstVeryLongName.ObjectA, FirstVeryLongName.ObjectB)
operation2(SecondVeryLongName.ObjectB, SecondVeryLongName.ObjectD)
...except that the repeated uses of the very long names add a lot of clutter.
Here is something I hoped would work, but doesn't seem to:
FirstVeryLongName.run {
operation1(ObjectA, ObjectB)
}
...which I wasn't able to make work, even if I tried moving ObjectA and ObjectB into the companion of FirstVeryLongName and writing
FirstVeryLongName.Companion.run { ... }
...which I had hoped would give unqualified access to the objects, as it would have for a val in the companion object.
One thing I specifically want to avoid is typealiases or importing them as aliased names. I want it to be obvious without cross-references or manually looking at the imports where these are all coming from.
Is there some trick that would let me write this code and write FirstVeryLongName, ObjectA, and ObjectB each exactly once?
It makes sense to me that it isn't working the way you tried it.
The class name itself is no instance and run or with therefore doesn't apply. It's the same as just writing the package name and nothing else. This doesn't work either.
Regarding the Companion-approach, I assume you implemented the following:
class FirstVeryLongName {
companion object {
object ObjectA
object ObjectB
object ObjectC
}
}
and a usage such as:
with(FirstVeryLongName.Companion) {
operation1(ObjectA, ObjectB)
}
Actually this could work as long as you have such properties defined for the companion (this applies to functions as well). Actually that is also something you mentioned yourself. You may want to look at the generated byte code to see what an object actually corresponds to, if you didn't do it already. If you did, you can skip the rest of this paragraph ;-) Think of it as if it were just nested classes. In the example above we therefore have 3 nested classes inside the Companion-class, which is inside the FirstVeryLongName-class.
From Kotlin the access to the singleton INSTANCE-field is hidden from you. In the Kotlin code FirstVeryLongName.Companion.ObjectA can represent both, the type and the singleton instance reference. The context is relevant.
As you can't use class-names-only or part of an import-statement in run/with, you can't also simplify the access to the singleton instance in this way.
You can however do something as follows. Note: I clearly do not recommend this approach as is (I do not believe that you really need both: the object and the val). Maybe you can also use an object expression there? There is most probably an easier way to structure your code, but without appropriate context I can only guess... I may be wrong):
class FirstVeryLongName {
companion object {
val ObjectA = FirstVeryLongName.ObjectA // can you use an object expression here?
val ObjectB = FirstVeryLongName.ObjectA
val ObjectC = FirstVeryLongName.ObjectA
}
object ObjectA
object ObjectB
object ObjectC
}
Now the run/with works as you desire, but now it actually accesses the val-reference which points to the object:
with(FirstVeryLongName.Companion) {
operation1(ObjectA, ObjectB)
}
Just showing a simple example using an object expression. You may either want to have a common superclass, interface or, if you do not mind, you can even use object : Any() here:
class FirstVeryLongName {
companion object {
val ObjectA = object : interfaces.ObjectA { /* ... */ }
// ...
}
}
Usage still looks the same. Now only the signature of operation1 may differ.

Inheriting private attributes in Perl 6

I can't find anything in the docs, but it seems that there is no access in a subclass to its superclass's private variables. Am I right?
class A {
has $!a;
}
class B is A {
has $.b;
method set_a($x) {
$!a = $x;
}
}
my $var = B.new();
$var.set_a(5);
say $var.a;
This gives an error message:
Attribute $!a not declared in class B
BTW where to read about Classes in the docs? I have only found a rather short section Classes and Objects.
In Perl 6, an attribute declared in a class is accessible only within that class. This means one can confidently refactor the state in the class without having to worry about any uses of that state outside of the class.
Subclasses do not receive any special access with regards to attributes. Some languages provide a protected modifier. This does not exist in Perl 6, by design. Either something is private to that class, or is exposed (like has $.a) to the outside world, since:
So far as that class is concerned, a subclass is part of the outside world.
Given the general advice is to "prefer composition over inheritance", it seems strange to privilege inheritance, or provide a mechanism that frustrates refactoring from inheritance to composition.
Attributes in a role, by contrast, are composed into the class, working as if they had been declared in the class itself. Therefore, an attribute from a composed role may be used in the class body. If looking to write re-usable pieces of functionality in an OO context, it's more typical to use roles and composition in Perl 6, not inheritance. Indeed, writing the original code as:
role A {
has $!a;
}
class B does A {
has $.b;
method set_a($x) {
$!a = $x;
}
method a() { $!a }
}
my $var = B.new();
$var.set_a(5);
say $var.a;
Works as desired.

Property 'sharedInstance' not found on object of type ClassA

I am creating a swift framework. In that one class is like this as shown below.
import Foundation
#objc public class classA: NSObject {
public override init (){
super.init();
}
/**
Singleton intance is returned.
*/
public class var sharedInstance: classA {
struct Static {
static let instance = popeye();
}
return Static.instance
}
}
Now when i add this framework into a Objective c project and try to access "sharedInstance" i get this error.
Property 'sharedInstance' not found on object of type ClassA.
Fix it Replace 'sharedInstance' with 'sharedInstance'
But even if i try use Fix it, this issue isnt solved.
NOTE: This issue doesn't happen when i integrate this framework with a swift project!!!
I AM STUCK.. :(
I tried to reproduce your problem. At first the syntax highlighter in Xcode flagged the same error in Objective-C that you mentioned, but the code actually was built and ran fine.
However, there is a cleaner way of doing this. In your code you are using a computed type property, which is evaluated every time you access it! You work around this by introducing the struct Static, where you essentially do what could be done in classA itself, like this:
/**
Singleton intance is returned.
*/
public static var sharedInstance: classA = popeye()
Here we used a stored type property, which is a recommended way to implement singletons, see here:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html
And here is some documentation on different kinds of properties:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html
Finally i was able to fix this with a minor change !! :)
Swift framework code
#objc class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
// the sharedInstance class method can be reached from ObjC
class func sharedInstance() -> SingletonTest {
return SingletonTest.swiftSharedInstance
}
// Some testing
func testTheSingleton() -> String {
return "Hello World"
}
}
Objective C parent project code
SingletonTest *aTest = [SingletonTest sharedInstance];
NSLog(#"Singleton says: %#", [aTest testTheSingleton]);