How to pass arguments from resolve() to callback specified in give()? - laravel-5

Constructor of class A requires an instance of class B, whose constructor in turn takes an optional string argument.
I want to be able to specify the value of that string argument to class B constructor when resolving class A. I want to do something like this in my service provider:
$this->app
->when(A::class)
->needs(B::class)
->give(function($argument_for_b /* <-- LOOK HERE */){
return new B($argument_for_b);
})
and then obtain instance of A like this (assuming A has been bound to AInterface in the container):
$aInstance = resolve(AInterface::class /* HOW TO PASS ARGUMENT FOR B? */);

Related

Difference between "def" and "static def" in Gradle

As the title, what is exactly the difference of these two defs in Groovy?
Maybe it's a documentation problem, I can't find anything...
A method declaration without static marks a method as an instance method. Whereas a declaration with static will make this method static - can be called without creating an instance of that class - see https://www.geeksforgeeks.org/static-methods-vs-instance-methods-java/
def in groovy defines a value as duck typed. The capabilities of the value are not determined by its type, they are checked at runtime. The question if you can call a method on that value is answered at runtime - see optional typing.
static def means that the method will return a duck typed value and can be called without having instance of the class.
Example:
Suppose you have these two classes:
class StaticMethodClass {
static def test(def aValue) {
if (aValue) {
return 1
}
return "0"
}
}
class InstanceMethodClass {
def test(def aValue) {
if (aValue) {
return 1
}
return "0"
}
}
You are allowed to call StaticMethodClass.test("1"), but you have to create an instance of InstanceMethodClass before you can call test - like new InstanceMethodClass().test(true).

How to detect if JavaScript (ES6) class has a non-default constructor?

I would like to know by some form of reflection or other means if a given ES6 class has a user-written non-default constructor, or not.
Assuming that user-provided constructor has one argument or more, you can do that by checking the length property of the function(class). But if the constructor takes no argument, there is simply no way as far as I know
function Person(fName, lName) {
this.firstName = fName;
this.lastName = lName
}
console.log(Person.length);
function Person2() {}
console.log(Person2.length);
class Person3 {
constructor(f,l) {}
}
console.log(Person3.length);
class Person4 {
}
console.log(Person4.length);
You can invoke the Classname.prototype.constructor.toString() (where Classname is the inspected class name) and get the source string for the class. Which you can then parse and see if it was a constructor declared or not.
Presumably, you need a decent parser for that, but it's another story.
References:
http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.tostring

How to load a constant complex object to a stack using LDCInsnNode in ASM

I want to use ASM library to create a bytecode method that is capable of returning a constant value at runtime. One of class in the ASM I can use is the LdcInsnNode. So my sample code is:
class Myclass{
final const Object value;
#Override
public MethodNode get(String clsName, String mhName){
int access = Opcodes.ACC_PUBLIC| Opcodes.ACC_STATIC;
MethodNode methodNode = new MethodNode(ASM5, access, mhName, type.toString(), null, null);
methodNode.instructions.add(new LdcInsnNode(value));
Type returnType = Type.getReturnType(type.toMethodDescriptorString());
if(!returnType.getInternalName().equals(Type.getDescriptor(value.getClass))){
methodNode.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, returnType.getInternalName()));
}
methodNode.instructions.add(new InsnNode(Opcodes.ARETURN));
return new methodNode;
}
}
My question is how to load value when it is an instance of complex type (user-defined class). The document for LdcInsnNode only says:
/**
* The constant to be loaded on the stack. This parameter must be a non null
* {#link Integer}, a {#link Float}, a {#link Long}, a {#link Double}, a
* {#link String} or a {#link org.objectweb.asm.Type}.
public LdcInsnNode(final Object cst) {
super(Opcodes.LDC);
this.cst = cst;
}
You can't.
The LDC* instructions only support (as of Java 7) ints, floats, longs, doubles, Strings, Classes, MethodHandles, and MethodTypes. It's a special instruction for bytecode level constants, not whatever random objects you might like to create.
You can push a null value with aconst_null, but apart from that you'll have to use normal code, i.e. create the object with new, then invokespecial the constructor with the desired arguments.
To add to the accepted answer:
Probably the easiest way to do this is to define your constant class value as a Singleton in a static field of another class. This can either be a class you write in Java or a synthetic class. Then, when you need the value, just use getstatic to put it on the stack.

How to create a new instance of a class from string?

In my PHP Extension (Written in C) I have a string with the class name. To be more precise, I have the namespace + class name. For example: Dumb\Factory
This class implements an interface defined in my extension which has a class entry
zend_class_entry *garlic_servicemanager_factoryinterface_ce;
and implements a public method named createService
Inside another class I have a method named get and I check to see if the parameter is a string. When it is a String I would like to instantiate the class and call that method, however I don't know how to instantiate the PHP class from within my C code.
How may I instantiate a class from a string so I can call the method defined by the interface?
You have to find the class_entry from the string and you can do it like below...
zend_class_entry *ce = NULL;
char *className = "Dumb\Factory";
zend_class_entry **pce;
if (zend_lookup_class(className, strlen(className ), &pce TSRMLS_CC) == FAILURE) {
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Class %s does not exist", className);
return;
}
ce = *pce;
// Now you have got "zend_class_entry" and
// now you can create N number of objects out of it.
// Check the Reflection API for more info.

Use of "#this" in Moles delegates

When I set a property of a moled type, it looks like they always require, as the first parameter, an object of the original moled type. I also noticed that some of the examples in the Moles Reference Guide assign this parameter as #this and I am trying to figure out why.
For instance, the original class looks something like this:
public class ProductDAO
{
internal void Insert(Product product, string id)
{
...
}
}
When I go to mole this method, the property is expecting a delegate whose first parameter is always the type of the moled object, in this case, a ProductDAO object. So in this case, the property is expecting a delegate of:
Action<ProductDAO, Product, string>
So do I always have to provide that moled object as the first parameter of my lambda expression? If so, what's the difference in using a regular variable name versus #this? What does #this mean/do?
MProductDAO.AllInstances.InsertProductString = (dao, product, id) => { };
versus
MProductDAO.AllInstances.InsertProductString = (#this, product, id) => { };

Resources