Recursive i itialization and how to use config group inside another config group - fb-hydra

I am exploring the options of the recursive initialization in hydra. I was able to setup a working example based on this PR. When trying more advanced stuff, I stumbled upon the following problem. My directory structure is as follows:
config/
config.yaml
/tokenizer
Tokenizer.yaml
/normalizer
Normalizer.yaml
The configs contain:
<config.yaml>
default:
- tokenizer: Tokenizer
<Tokenizer.yaml>
_target_: some.path.Tokenizer
normalizer: Normalizer # I want this to be the Normalizer object after instantiation, but getting string.
<Normalizer.yaml>
_target_: some.other.path.Normalizer
arg1: value1
I want to recursively instantiate the Tokenizer without the need to explicitly write all the arguments of the Normalizer since all of them are already mentioned in the Normalizer.yaml file. In other words, I would like to use the normalizer config group inside tokenizer config group. Right now, if I call tokenizer = instantiate(cfg.tokenizer), the result is a Tokenizer class object, but tokenizer.normalizer is a string Normalizer. If I use value interpolation and setup the project as follows:
<config.yaml>
default:
- tokenizer: Tokenizer
- normalizer: Normalizer
<Tokenizer.yaml>
_target_: some.path.Tokenizer
normalizer: ${normalizer}
<Normalizer.yaml>
_target_: some.other.path.Normalizer
arg1: value1
The resulting variable tokenizer.normalizer is a dict containing args for Normalizer like so{"_target_": ...} instead of being an initialized Normalizer class. How can I avoid the need to explicitly repeat the definition of the normalizer inside the tokenizer config?

I don't think what you want is supported right now.
Please file a feature request with a minimal config, and an explanation of the current behavior and the desired behavior.

Related

How to getRepository() for entity in subfolder with symfony 5.4?

Prior to Symfony 5.4 I used to reference my entities like this
public function findAction($archived = false)
{
$em = $this->getDoctrine()->getManager();
$analyses = $em->getRepository('App:Hazardlog\Analysis')->findAll();
I remember there was a new syntax for it ending with ::class a while back (possibly already in symfony 4) but I've been hanging on to this syntax because I have my entities organized into subfolders (a remnant from the old days when code in src was supposed to reside in a bunch of bundles...).
However, now all I get is a neat error saying
Class 'Analysis::class' does not exist
This is my directory structure
Entity
Hazardlog
Analysis
Risk
Now, I have tried a number of ways to reference my entities with the ::class at the end, but none seem to work.
Can I simply not keep my directories in symfony 5.4 or is there a way of doing it that I just didn't find?
I've tried
$analyses = $em->getRepository('App:Hazardlog\Analysis::class')->findAll();
Also tried
$analyses = $em->getRepository('Hazardlog\Analysis::class')->findAll();
As well as
$analyses = $em->getRepository('Analysis::class')->findAll();
(last one was a longshot I know, but since there is only one Analysis entity in the app, and symfony is set on a new syntax, I thought maybe symfony would be smart enough to find it anyways 😂)
Any hints for me here?
------------------ UPDATE ---------------
From Cerad's comment I learned a few more ways that won't work
$analyses = $em->getRepository('App\Entity\Hazardlog\Analysis::class')->findAll();
$analyses = $em->getRepository('App\Entity\Hazardlog\Analysis\Analysis::class')->findAll();
And the way that actually works is
$analyses = $em->getRepository('App\Entity\Hazardlog\Analysis')->findAll();
Though I'm not sure if it's a bad idea to go with that, or if I should start referencing it with that "::class" appendage. What difference does it make?
Enclosing a bunch of characters in single quotes (') makes it a string. Therefore 'App\Entity\Hazardlog\Analysis::class' is a string. And that string is invalid as an argument to the getRepository method because it is not a valid classname. Therefore you need to use ->getRepository('App\Entity\Hazardlog\Analysis') instead - as that is the valid fully-qualified classname.
Instead, using Analysis::class (notice, no quotes). Is a shortcut in php to create the valid fully-qualified classname for the class. So, you could use ->getRepository(Analysis::class) (again, no quotes) and php will convert the value. You will also notice in this case, that you must import the class - so up at the top of your class, you will have something like import App\Entity\Hazardlog\Analysis;. Without the import the ::class trick doesn't do its job.
In the end, they are functionally the same. It is your preference which to use.

self-referential generic types in flowtype

I'm trying to build a better Flowtype definition for Koa library and am kinda stuck.
My idea was to use Generic types to be able to specify customized Context class to Koa, so we can actually typecheck additional fields (populated by middlewares) instead of treating them as any.
so, I have:
declare type Context {…}
declare class Application<T: Context<T>> extends events$EventEmitter {
context: T,
…
}
fine…
but Context has a back-reference to Application, which is a generic dependent on Context. How do I spell this in typelib?
This doesn't look right, as I actually want to use not original Context but the type which was actually used by user
declare type Context {
app: Application<Context>
}

Symfony 4: bind vs arguments keyword to explicitly inject dependency

As far as I am concerned there are two ways (both working properly for me) to explicitly inject a dependency to a service:
a) using the bind keyword
App\Service\ServiceA:
bind:
$myService: '#myserviceid'
b) using the arguments keyword
App\Service\ServiceA:
arguments:
$myService: '#myserviceid'
Is there any difference between them? Thank you!
Bind is used in defaults configurations for services, for exemple to define scalar arguments for all services. It can be like the autowire, but the difference is that this last one can't autowire scalar arguments (e.g. strings and numbers). It's new in SYmfony 3.4.
You can check the doc here: https://symfony.com/blog/new-in-symfony-3-4-local-service-binding

Does Kotlin compiler always retain parameter names in bytecode?

In kotlin-reflect, class KParameter has nullable name, and its KDoc says:
Name of this parameter as it was declared in the source code, or null if the parameter has no name or its name is not available at runtime. Examples of nameless parameters include this instance for member functions, extension receiver for extension functions or properties, parameters of Java methods compiled without the debug information, and others.
It says about well-known fact that Java doesn't always include parameter names in bytecode, but it says nothing about Kotlin classes, though there are some others.
Can I assume that Kotlin compiler retains parameter names declared for functions in Kotlin sources? (In particular, I need constructor parameter names).
Just to complete Alexander's answer above as it may not be immediately obvious, to provide parameter names for Java reflection of Kotlin classes (i.e. for Java code using reflection to view parameter names of Kotlin code), you must supply the -java-parameters argument (since Kotlin 1.1).
Gradle
In your build.gradle > compileKotlin closure
compileKotlin {
kotlinOptions {
jvmTarget = '1.8' //Good to target Java 8 unless you need 7
javaParameters = true //Will retain parameter names for Java reflection
}
}
Maven
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<args>
<arg>-java-parameters</arg>
</args>
...
IntelliJ
In Preferences > Kotlin Compiler > Additional command line parameters
Append -java-parameters to the list
Ensure you run a clean before running any reflection based code.
Unless the bytecode was modified in some way, it's safe to assume that all parameters which are given names in the sources will have those names at runtime. This is true for Kotlin 1.0 and there's no plans to change this.
If you're interested which unnamed parameters does others include, there's also the single parameter of a default property setter and the outer class parameter for an inner class constructor. Such parameters don't have names neither in the source code nor at runtime.
UPD: since this may seem confusing to some, this question and the answer are only related to retaining parameter names for Kotlin reflection and specifically so that KParameter.name would work. This is not related to the parameter names that Java reflection would see for compiled Kotlin code. To retain parameter names for Java reflection, pass the -java-parameters option to the Kotlin compiler.

Symfony2 - use parameters on config.yml for the arguments of a service

I'm trying to use the method described on this other question and I wasn't able to make it work:
Symfony2: How to inject ALL parameters in a service?
In summary, I would like to define the arguments of my service in a unique file using a variable. I would then only pass this variable as an argument to my service. If one day, I decide to change the arguments, I don't have to change all the calls on my service. I would just change the content of this variable. However, I'm having the following error:
Symfony\Component\DependencyInjection\Exception\InvalidArgumentException You cannot dump a container with parameters that contain references to other services (reference to service "doctrine.orm.entity_manager" found in "/company.usermanagerservice/em").
Was anybody able to make it work? Or do you have other ideas?
Edit:
services.yml:
company.user_manager:
class: Company\CoreBundle\Model\UserManager
arguments: [%company.userManagerService%]
Then on config.yml:
parameters:
company.userManagerService:
em: 'doctrine.orm.entity_manager'
user_helper: 'company.helper.user'
fos_manipulator: 'fos_user.util.user_manipulator'

Resources