Can't hide constructor at [incr Tcl] - oop

Consider the code below.
package require Itcl
::itcl::class A \
{
private {
constructor { } { } { puts "==== at A::constructor" }
method f { } { puts "==== at A::f" }
}
}
A a ;# PASSES
a f ;# fails
For class A the constructor is private, but it is still possible to define an object of A.
Am I doing something wrong, or incr Tcl is designed to behave so?

I believe this is the way itcl work, if you look at the specification for a class:
itcl::class className {
inherit baseClass ?baseClass...?
constructor args ?init? body
destructor body
method name ?args? ?body?
proc name ?args? ?body?
variable varName ?init? ?config?
common varName ?init?
public command ?arg arg ...?
protected command ?arg arg ...?
private command ?arg arg ...?
set varName ?value?
array option ?arg arg ...?
}
className objName ?arg arg ...?
objName method ?arg arg ...?
className::proc ?arg arg ...?
you can see that private/protected can be applied to command but not to the constrcutor or the destructor. Looking here at the documentation on the itcl design patterns may also give some clues as to how to achieve something close to a private constructor.

Related

Mocking BiFunction with Spock Java/Groovy

Pretty new to Spock. Trying to mock a function that returns a BiFunction unsuccessfully.
The function looks like
public interface myInterface {
Optional<BiFunction<Object, Object, Object>> myAwesomeFunc()
}
Trying to mock like
def mockBiFunction = Mock(BiFunction)
mockMyInterface.myAwesomeFunc >> mockBiFunction
mockBiFunction.apply(*_) >> mockReturnVal
This results in
No signature of method: com.sun.proxy.$Proxy49.apply() is applicable for argument types: (org.spockframework.lang.SpreadWildcard) values: [*_]
Possible solutions: apply(java.lang.Object, java.lang.Object), any(), any(groovy.lang.Closure), every(), tap(groovy.lang.Closure), every(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: com.sun.proxy.$Proxy49.apply() is applicable for argument types: (org.spockframework.lang.SpreadWildcard) values: [*_]
Possible solutions: apply(java.lang.Object, java.lang.Object), any(), any(groovy.lang.Closure), every(), tap(groovy.lang.Closure), every(groovy.lang.Closure)
Tried with
mockBiFunction(*_) >> mockReturnVal
That doesn't work either.
Edit:
Tried with
mockBiFunction.apply(object1, object2) >> mockReturnVal
This fails with
Cannot invoke method rightShift() on null object
java.lang.NullPointerException: Cannot invoke method rightShift() on null object
When I have mocked it then why is it null ??
Actually, your interface method returns an Optional, not a BiFunction. More precisely, it returns Optional<BiFunction<Object, Object, Object>>. Therefore, your interface mock needs to return an Optional as well when stubbing myAwesomeFunc(). That is what IMO is wrong with your code.
Your own answer does not look logical to me, but that might be because both in your question and your answer you only provided incoherent sets of snippets instead of a proper MCVE. Please do learn how to ask good questions. You seem to be an experienced developer, wrestling with optionals of bi-functions etc. Therefore, you ought to know how to make your problem reproducible. If you are unable to do that, you cannot expect good answers or people even feeling inclined to try.
Anyway, here is my take:
package de.scrum_master.stackoverflow.q71602791
import spock.lang.Specification
import java.util.function.BiFunction
class BiFunctionMockTest extends Specification {
def "mock BiFunction"() {
given:
def biFunction = Mock(BiFunction) {
apply(*_) >> "dummy"
}
def myInterface = Mock(MyInterface) {
myAwesomeFunc() >> Optional.of(biFunction)
}
def underTest = new MyInterfaceUser(myInterface: myInterface)
expect:
underTest.doSomething().get().apply("foo", "bar") == "dummy"
}
interface MyInterface {
Optional<BiFunction<Object, Object, Object>> myAwesomeFunc()
}
static class MyInterfaceUser {
MyInterface myInterface
def doSomething() {
myInterface.myAwesomeFunc()
}
}
}
Ah looks like all I had to do was to use a function as the mock return value from the BiFunction so something like following works
def mockMyAwesomeFunc = abc -> mockReturnVal
mockBiFunction.apply(object1, object2) >> mockMyAwesomeFunc
instead of doing
mockBiFunction.apply(object1, object2) >> mockReturnVal
Feeling really stupid now !!
Edit -- Updating the answer to more closely reflect the actual working code - this is what worked
def mockBiFunction = Mock(BiFunction)
mockMyInterface.myAwesomeFunc >> Optional.of(mergeBiFunction)
mergeBiFunction.apply(_, _) >> (a, b) -> {
return mockValue
}

create a class object as variable in Tcloo

I start to use tclOO.
I need to create a Aclass instance anotherClassIns in my main class MainClass as below:
oo:class create Aclass {
variable num;
constructor {argv} {
set num [lindex $argv 0]
}
}; #end of Aclass
oo:class create MainClass {
variable anotherClassIns ; # this variable is another class's instance!
constructor {argv} {
Aclass create anotherClassIns {$argv};
}
}
And in main function, I create a MainClass instance:
MainClass create Ins $argv
If I want to print $num in Aclass, how can I do?
Thanks.
All instance variables in TclOO have globally-addressable names so that they can be used with other parts of Tcl that expect such (especially vwait and trace, but also Tk's -textvariable options).
The easiest way for now is to make an accessor method:
oo:class create Aclass {
variable num
constructor {argv} {
set num [lindex $argv 0]
}
method num {} {
return $num
}
}
oo:class create MainClass {
variable anotherClassIns
constructor {argv} {
set anotherClassIns [Aclass new {*}$argv]
}
destructor {} {
# Assuming you're owning the inner instance
$anotherClassIns destroy
}
method printTheValue {} {
puts [$anotherClassIns num]
}
}
You can also access the variable directly by using the fact that variables exist in a namespace, and that namespace can be looked up with info object namespace:
method printTheValue {} {
# Probably easiest to do this
namespace upvar [info object namespace $anotherClassIns] num v
puts $v
}
But that won't work with 8.7's private variables, as those are name-mangled in a way that is decidedly non-accessible to outside code. In that case, you'd need to get Aclass to provide access into its internals; that's literally the point of private variables. The varname method of oo::object can help there; it's not exposed by default, but it's available internally via my, and you can expose it for a class or even just an instance via the export definition.
# Probably at object creation time
oo::objdefine $anotherClassIns export varname
# Then, to access
puts [set [$anotherClassIns varname num]]
# Or
upvar 0 [$anotherClassIns varname num] v
puts $v
There's a similar variable method, but that requires that you don't have a colliding local num variable:
# Object creation time
oo::objdefine $anotherClassIns export variable
# Access
$anotherClassIns variable num
puts $num

Making a custom declarator

Let's say I use a certain set of boilerplate fairly regularly:
class Foo {
method abc($a: $b, $c, +#d) is pure {
use Slang::Bar;
…
}
method xyz($a: $b, $c, +#d) is pure {
use Slang::Bar;
…
}
method blarg($a: $b, $c, +#d) is pure {
use Slang::Bar;
…
}
}
I'd rather be able to just say:
class Foo is/does Bar {
bar abc { … }
bar xyz { … }
bar blarg { … }
}
And somewhere in Bar, set up the declaration for bar (or, since class Foo will itself ultimately use its own declarator, it could go somewhere else and doesn't have to be pulled out in a separate Type). How would I go about doing that?
-1. Limitations (only for packages)
The method EXPORTHOW calls .set_how on current $?LANG adding a slang to the latter.
Then it add_package_declarator to the MAIN $?LANG which adds a package_declarator method to its Actions and Grammar. It is, I think, the only "dynamic slang" (in World.nqp).
If what you want is to overwrite routine_declarator. Then you have to write a slang imitating the chain just cited.
If you accept to keep the method keyword and make the automatic signature in the class, say according to the method name, here is a way:
Note: A Package is a container (package, grammar, module, role, knowhow, enum, class, subset). If you put code inside like a method, this gets executed (I'v just tried):
0. Description (EXPORTHOW)
I would use undocumented EXPORTHOW and DECLARE in a module because I did not find a way with Phaser. Apparently it is too late even at BEGIN.
The example I give, is decorating every method in a class (even BUILDALL).
1. Lib (decorator.rakumod)
class DecoratedClassHOW is Metamodel::ClassHOW {
method add_method(Mu $obj, $name, $code_obj) {
sub wrapper ($obj, $a, $b) {
say "Before $name";
my $res = $code_obj($obj, $a, $b);
say "After $name";
return $res;
}
my $res = callwith($obj, $name, &wrapper);
return $res;
}
}
my module EXPORTHOW {
package DECLARE {
constant decorated = DecoratedClassHOW;
}
}
2. Executable
use lib '.';
use decorator-lib;
decorated Foo {
method abc($a, $b) {
say "In abc: $a:$b";
}
}
my $f = Foo.new;
$f.abc(1, 2);
3. Output
Before BUILDALL
After BUILDALL
Before abc
In abc: 1:2
After abc
4. Sources
Grammar::Debugger: exporting a symbol (grammar) overriding find_method and add_method
And npq's NQPTraceHOW::trace-on: Looping with for $_.HOW.method_table($_) creating a new hash overwriting the method cache with the (well-named) nqp::setmethcache.
To automatize the signature, play with .signature
Jnthn article on EXPORTHOW
So post on EXPORTHOW impossible with role

PHP Static and Normal Functions Calling [duplicate]

There are two distinct ways to access methods in PHP, but what's the difference?
$response->setParameter('foo', 'bar');
and
sfConfig::set('foo', 'bar');
I'm assuming -> (dash with greater than sign or chevron) is used for functions for variables, and :: (double colons) is used for functions for classes. Correct?
Is the => assignment operator only used to assign data within an array? Is this in contrast to the = assignment operator which is used to instantiate or modify a variable?
When the left part is an object instance, you use ->. Otherwise, you use ::.
This means that -> is mostly used to access instance members (though it can also be used to access static members, such usage is discouraged), while :: is usually used to access static members (though in a few special cases, it's used to access instance members).
In general, :: is used for scope resolution, and it may have either a class name, parent, self, or (in PHP 5.3) static to its left. parent refers to the scope of the superclass of the class where it's used; self refers to the scope of the class where it's used; static refers to the "called scope" (see late static bindings).
The rule is that a call with :: is an instance call if and only if:
the target method is not declared as static and
there is a compatible object context at the time of the call, meaning these must be true:
the call is made from a context where $this exists and
the class of $this is either the class of the method being called or a subclass of it.
Example:
class A {
public function func_instance() {
echo "in ", __METHOD__, "\n";
}
public function callDynamic() {
echo "in ", __METHOD__, "\n";
B::dyn();
}
}
class B extends A {
public static $prop_static = 'B::$prop_static value';
public $prop_instance = 'B::$prop_instance value';
public function func_instance() {
echo "in ", __METHOD__, "\n";
/* this is one exception where :: is required to access an
* instance member.
* The super implementation of func_instance is being
* accessed here */
parent::func_instance();
A::func_instance(); //same as the statement above
}
public static function func_static() {
echo "in ", __METHOD__, "\n";
}
public function __call($name, $arguments) {
echo "in dynamic $name (__call)", "\n";
}
public static function __callStatic($name, $arguments) {
echo "in dynamic $name (__callStatic)", "\n";
}
}
echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";
echo '$b->func_instance():', "\n", $b->func_instance(), "\n";
/* This is more tricky
* in the first case, a static call is made because $this is an
* instance of A, so B::dyn() is a method of an incompatible class
*/
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
* instance of B (despite the fact we are in a method of A), so
* B::dyn() is a method of a compatible class (namely, it's the
* same class as the object's)
*/
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";
Output:
B::$prop_static: B::$prop_static value
B::func_static(): in B::func_static
$b->prop_instance: B::$prop_instance value
$b->func_static(): in B::func_static
$b->func_instance():
in B::func_instance
in A::func_instance
in A::func_instance
$a->dyn():
in A::callDynamic
in dynamic dyn (__callStatic)
$b->dyn():
in A::callDynamic
in dynamic dyn (__call)
:: is used in static context, ie. when some method or property is declared as static:
class Math {
public static function sin($angle) {
return ...;
}
}
$result = Math::sin(123);
Also, the :: operator (the Scope Resolution Operator, a.k.a Paamayim Nekudotayim) is used in dynamic context when you invoke a method/property of a parent class:
class Rectangle {
protected $x, $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}
class Square extends Rectangle {
public function __construct($x) {
parent::__construct($x, $x);
}
}
-> is used in dynamic context, ie. when you deal with some instance of some class:
class Hello {
public function say() {
echo 'hello!';
}
}
$h = new Hello();
$h->say();
By the way: I don't think that using Symfony is a good idea when you don't have any OOP experience.
Actually by this symbol we can call a class method that is static and not be dependent on other initialization...
class Test {
public $name;
public function __construct() {
$this->name = 'Mrinmoy Ghoshal';
}
public static function doWrite($name) {
print 'Hello '.$name;
}
public function write() {
print $this->name;
}
}
Here the doWrite() function is not dependent on any other method or variable, and it is a static method. That's why we can call this method by this operator without initializing the object of this class.
Test::doWrite('Mrinmoy');
// Output: Hello Mrinmoy.
But if you want to call the write method in this way, it will generate an error because it is dependent on initialization.
The => operator is used to assign key-value pairs in an associative array. For example:
$fruits = array(
'Apple' => 'Red',
'Banana' => 'Yellow'
);
It's meaning is similar in the foreach statement:
foreach ($fruits as $fruit => $color)
echo "$fruit is $color in color.";
The difference between static and instantiated methods and properties seem to be one of the biggest obstacles to those just starting out with OOP PHP in PHP 5.
The double colon operator (which is called the Paamayim Nekudotayim from Hebrew - trivia) is used when calling an object or property from a static context. This means an instance of the object has not been created yet.
The arrow operator, conversely, calls methods or properties that from a reference of an instance of the object.
Static methods can be especially useful in object models that are linked to a database for create and delete methods, since you can set the return value to the inserted table id and then use the constructor to instantiate the object by the row id.
Yes, I just hit my first 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. My bad, I had a $instance::method() that should have been $instance->method(). Silly me.
The odd thing is that this still works just fine on my local machine (running PHP 5.3.8) - nothing, not even a warning with error_reporting = E_ALL - but not at all on the test server, there it just explodes with a syntax error and a white screen in the browser. Since PHP logging was turned off at the test machine, and the hosting company was too busy to turn it on, it was not too obvious.
So, word of warning: apparently, some PHP installations will let you use a $instance::method(), while others don't.
If anybody can expand on why that is, please do.

Static function inheritance in [incr Tcl]

Inheritance in incr Tcl doesn't work as expected. Consider the code below.
package require Itcl
::itcl::class Base \
{
public {
proc function { } { puts "==== Base::function" }
}
}
::itcl::class Derived { inherit Base }
Base::function
Derived::function ;# FAILS
The last line fails, so Base::function is not inherited at Derived, though Derived inherits from Base.
Am I doing something wrong, or incr Tcl is designed to behave so?
Reading the docs I don't think that procs in an itcl class work the way you think they ought to:
proc name ?args? ?body?
Declares a proc called name. A proc is an ordinary procedure within
the class namespace. Unlike a method,
a proc is invoked without referring to
a specific object. When the proc body
is executed, it will have automatic
access only to common data members.
If the args list is specified, it establishes the usage information for
this proc. The body command can be
used to redefine the proc body, but
the args list must match this
specification.
Within the body of another class method or proc, a proc can be invoked
like any other command-simply by using
its name. In any other namespace
context, the proc is invoked using a
qualified name like "className::proc".
Procs in a base class that are
redefined in the current class, or
hidden by another base class, can also
be accessed via their qualified name.
My reading of this is that the proc is associated with it's class, it can be referred to in the derived class but it isn't defined in it. For example the following works:
package require Itcl
::itcl::class Base {
public {
proc function { } { puts "==== Base::function" }
}
}
::itcl::class Derived {
inherit Base
public {
proc function { } {
puts "==== Derived::function"
return [Base::function]
}
}
}
Base::function
Derived::function ;# FAILS
The proc you defined Base::function is (more or less) a regular proc in the namespace Base. When you inherit in Itcl, you just inherit methods, you don't inherit procs. In a related note, you cannot call the proc function from an instance of Base, you have to call it like any regular proc.
itcl::class Base {
public {
proc function { } { puts "==== Base::function" }
}
public method test {} {
$this function
}
public method test2 {} {
function
}
}
Base bb
bb test ;# yields error: bad option "function"
bb test2 ;# works as expected