Skip to content

Commit

Permalink
New Crowdin translations by GitHub Action (#195)
Browse files Browse the repository at this point in the history
Co-authored-by: Crowdin Bot <[email protected]>
  • Loading branch information
github-actions[bot] and crowdin-bot authored Jul 4, 2024
1 parent f99864a commit f1e16d3
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
97 changes: 97 additions & 0 deletions src/i18n/en-US/docusaurus-plugin-content-docs/current/faq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,100 @@ title: "frequently asked questions"
slug: "/Frequently asked questions"
---

<br/>

### I want to use lightweight dynamic compilation. I heard that Natasha requires several tens of megabytes of memory for preheating, and the packaged size also increases. I feel it's too heavy.

Answer: The preheating of Natasha is designed for beginners, the original intention is to ignore all preparation work and directly perform dynamic compilation.However, whether it's emitting or expression tree, both require reflection-related metadata for dynamic compilation. If you have experience with emitting and expression tree programming, you will know what metadata your dynamically written functions rely on. Natasha can skip preheating and support custom metadata addition. See the following example, where the input is value and the output is Math.Floor(value/0.3):

#### Emit version
```cs
DynamicMethod dynamicMethod = new DynamicMethod("FloorDivMethod", typeof(double), new Type[] { typeof(double) }, typeof(Program).Module);

ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_R8, 0.3);
ilGenerator.Emit(OpCodes.Div);
ilGenerator.Emit(OpCodes.Call, typeof(Math).GetMethod("Floor", new Type[] { typeof(double) }));
ilGenerator.Emit(OpCodes.Ret);

Func<double, double> floorDivMethod = (Func<double, double>)dynamicMethod.CreateDelegate(typeof(Func<double, double>));
```

#### Expression tree version
```cs
ParameterExpression valueParameter = Expression.Parameter(typeof(double), "value");

Expression divisionExpression = Expression.Divide(valueParameter, Expression.Constant(0.3));
Expression floorExpression = Expression.Call(typeof(Math), "Floor", null, divisionExpression);

Expression<Func<double, double>> expression = Expression.Lambda<Func<double, double>>(floorExpression, valueParameter);

Func<double, double> floorDivMethod = expression.Compile();
```

#### Natasha version
```cs
AssemblyCSharpBuilder builder = new();
var func = builder
.UseRandomLoadContext()
.UseSimpleMode()
.ConfigLoadContext(ctx => ctx
.AddReferenceAndUsingCode(typeof(Math))
.AddReferenceAndUsingCode(typeof(double)))
.Add("public static class A{ public static double Invoke(double value){ return Math.Floor(value/0.3); }}")
.GetAssembly()
.GetDelegateFromShortName<Func<double, double>>("A", "Invoke");
```

#### Natasha method template encapsulation version
> This extension library `DotNetCore.Natasha.CSharp.Extension.MethodCreator` is encapsulated based on the original Natasha and released after version 9.0 of Natasha.
```cs
var simpleFunc = "return Math.Floor(arg1/0.3);"
.WithSimpleBuilder()
.WithMetadata(typeof(Math))
.ToFunc<double, double>();
```

The above two dynamic compilations of Natasha will not cause a memory increase of tens of megabytes, they belong to on-demand construction. At the same time, it can be seen that no matter which dynamic construction, it cannot escape the constraint of `typeof(Math)`. Natasha also supports lightweight construction, which is even more concise.

### Can I use Natasha as a rule engine?

A: The dynamic construction ability of Natasha is very powerful. It can be used as the basis for developing other libraries, which was also the original intention of developing this library. You can use Natasha to encapsulate your own rule engine.

### I don't want to compile every time, can I cache the result of the script?

A: No, caching the result needs to be done by you. Natasha follows the lightweight route. `AssemblyCSharpBuilder` is the smallest and most basic compilation unit. If you want to cache, you can implement a ConcurrentDictionary<string,Delegate/Action/Func> to cache the result.Natasha is not responsible for anything other than the compilation responsibility.

### I only want to use the using statement, but I don't want to add so many references.

A: Natasha supports only preheating using without adding references after version 9.0, and a new initialization method is added:
```cs
NatashaManagement
.GetInitializer()
.WithMemoryUsing()
//.WithRefUsing()
//.WithMemoryReference()
//.WithRefReference();
//.WithExcludeReferences((asm, @namespace) =>
//!string.IsNullOrWhiteSpace(@namespace) &&
//@namespace.StartsWith("Microsoft.VisualBasic"))
.Preheating<NatashaDomainCreator>();
```
### Can the previously created compilation units be reused?

A: Before Natasha v9.0, reuse is not recommended. After v9.0, the Api: `Reset` is introduced. This method has very detailed comments to guide and remind you of the reuse considerations you need to pay attention to.

### If you don't understand metadata and don't want to manage using, can you write reliable dynamic functional logic?

A: It's quite challenging. Even with Natasha fully preheated, it is inevitable to encounter various inconsistencies caused by complex environments and excessive use of 'using' statements.Take a simple example:
```cs
namespace MyNamespace{

public static class File{

}
}
```
Even with implicit 'using' enabled in VS, the code above still cannot handle the issue of ambiguous reference between 'File' in 'System.IO' and 'MyNamespace'. And sometimes, Natasha's preheating with 'using' statements may cover more extensively than that in VS, which may increase the probability of errors. This requires coding conventions to constrain developers, such as avoiding class names defined by official sources and using class name extensions, for example, using 'System.IO.File' to avoid conflicts in namespace references.
97 changes: 97 additions & 0 deletions src/i18n/ja-JP/docusaurus-plugin-content-docs/current/faq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,100 @@ title: "よくある質問です"
slug: "/よくある質問"
---

<br/>

### 私は軽量な動的コンパイルを使用したいと思っています。Natashaはいくつかの十数メガバイトのメモリを事前にロードする必要があり、パッケージのサイズも増加すると聞きましたが、私にとっては重すぎると感じます。

答:Natashaのプレヒートは初心者向けであり、すべての準備作業を無視して直接動的コンパイルを行うことを意図しています。しかし、emitまたは式木の場合、動的コンパイルに必要なリフレクション関連のメタデータが提供される必要があります。emitおよび式木のプログラミング経験があれば、自分が書いた動的機能がどのようなメタデータに依存しているかを知ることができるはずですが、Natashaは事前ロードせずにカスタムのメタデータを追加することもできます。以下の例をご覧ください。この例では、入力はvalueで、出力はMath.Floor(value/0.3)です。

#### emitバージョン
```cs
DynamicMethod dynamicMethod = new DynamicMethod("FloorDivMethod", typeof(double), new Type[] { typeof(double) }, typeof(Program).Module);

ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_R8, 0.3);
ilGenerator.Emit(OpCodes.Div);
ilGenerator.Emit(OpCodes.Call, typeof(Math).GetMethod("Floor", new Type[] { typeof(double) }));
ilGenerator.Emit(OpCodes.Ret);

Func<double, double> floorDivMethod = (Func<double, double>)dynamicMethod.CreateDelegate(typeof(Func<double, double>));
```

#### 式木のバージョン
```cs
ParameterExpression valueParameter = Expression.Parameter(typeof(double), "value");

Expression divisionExpression = Expression.Divide(valueParameter, Expression.Constant(0.3));
Expression floorExpression = Expression.Call(typeof(Math), "Floor", null, divisionExpression);

Expression<Func<double, double>> expression = Expression.Lambda<Func<double, double>>(floorExpression, valueParameter);

Func<double, double> floorDivMethod = expression.Compile();
```

#### Natashaのバージョン
```cs
AssemblyCSharpBuilder builder = new();
var func = builder
.UseRandomLoadContext()
.UseSimpleMode()
.ConfigLoadContext(ctx => ctx
.AddReferenceAndUsingCode(typeof(Math))
.AddReferenceAndUsingCode(typeof(double)))
.Add("public static class A{ public static double Invoke(double value){ return Math.Floor(value/0.3); }}")
.GetAssembly()
.GetDelegateFromShortName<Func<double, double>>("A", "Invoke");
```

#### Natashaメソッドテンプレートラッパーバージョン
> この拡張ライブラリ`DotNetCore.Natasha.CSharp.Extension.MethodCreator`は、元のNatashaを基にしており、Natasha v9.0以降で利用できます。
```cs
var simpleFunc = "return Math.Floor(arg1/0.3);"
.WithSimpleBuilder()
.WithMetadata(typeof(Math))
.ToFunc<double, double>();
```

以上の2つのNatashaの動的コンパイルでは、数十Mのメモリ使用量の増加は発生せず、必要に応じて構築されます。 同時に、どちらの動的ビルド方法を使用しても、`typeof(Math)`からは逃れることはできませんが、Natashaは軽量なビルドもサポートしており、さらにシンプルです。

### Natashaをルールエンジンとして使用できますか?

答:Natashaの動的ビルド能力は非常に強力であり、他のライブラリの基礎として使用することができます。これは私がこのライブラリを開発する際の本意でもあり、Natashaを使用して独自のルールエンジンを作成することができます。

### スクリプトの結果をキャッシュしたくありません。毎回コンパイルするのは嫌ですか?

答え:できません。結果をキャッシュするには、自分でConcurrentDictionary<string,Delegate/Action/Func>を実装する必要があります。Natashaは軽量化路線を歩んでおり、`AssemblyCSharpBuilder`が最小限の基本的なコンパイルユニットです。Natasha 不负责<span class="notranslate">编译职责之外</span>的事情。

### 我只想使用 <span class="notranslate">using</span> 全集,但不想添加那么多的引用。

答:Natasha 在 v9.0 版本后支持只预热 <span class="notranslate">using</span> 而不添加引用,新增了初始化方法:
```cs
NatashaManagement
.GetInitializer()
.WithMemoryUsing()
//.WithRefUsing()
//.WithMemoryReference()
//.WithRefReference();
//.WithExcludeReferences((asm, @namespace) =>
//!string.IsNullOrWhiteSpace(@namespace) &&
//@namespace.StartsWith("Microsoft.VisualBasic"))
.Preheating<NatashaDomainCreator>();
```
### 能否复用之前创建的编译单元?

答:Natasha v9.0 之前不推荐复用,v9.0 后推出了 Api : `Reset`. 该方法有非常详细的注释引导和提示您需要注意的复用事项。

### 如果不懂元数据,也不想理 <span class="notranslate">using</span> 管理,能否写出一手好的可靠的动态功能逻辑?

答:かなり厳しいです。Natashaは完全にプレヒートされた状態でも、複雑な環境によってさまざまなバージョンの不一致やusingの誤用などが避けられません。就拿简单的例子来说:
```cs
namspace MyNamespace{

public static class File{

}
}
```
上記のコードでは、VSが暗黙的なusingの場合でも、System.IOとMyNamespaceの間のFileの参照が不明な問題を処理できません。 そして、Natashaのusingのプレヒートは、VSのusingよりもより包括的なカバレッジを持つことがあり、したがってエラーの発生確率がより高くなる可能性があります。 这需要编码规范来约束开发者,比如避开官方定义的类名,扩展类名等,比如使用 <span class="notranslate">System.IO.File</span> 避开命名空间引用冲突的问题。

0 comments on commit f1e16d3

Please sign in to comment.