AmberDB

 view release on metacpan or  search on metacpan

docs/EN.AmberDB-Locale_User-Guide.md  view on Meta::CPAN

`AmberDB::Locale` is a **locale-aware text processing engine** designed for multilingual applications. Written in Perl, it provides the following core capabilities:

| Capability | Description |
|---|---|
| Case conversion | Locale-aware `uc`, `lc`, `ucfirst` |
| Sorting | Unicode Collation Algorithm (UCA) based |
| ASCII transliteration | Convert accented characters to plain ASCII (slugs, IDs) |
| Number → Text | Written-out numbers for invoices/documents |
| Date/time formatting | Locale-specific date formats |
| Number/currency formatting | Grouping separators, decimal separators, symbol placement |
| HTML entity decoding | Named + numeric entity decode |
| Plural rules | CLDR-based plural form selection |
| UTF-8 safe substring | Character-based slicing (not byte-based) |

**Architectural principle:** Engine logic lives in `AmberDB::Locale.pm`, while language data resides in `AmberDB::Locale::Lang::*` packages as **pure data**. Engine and data are completely separated.

---

## 2. Architecture

```
AmberDB::Locale                 ← Main engine (all logic here)
├── AmberDB::Locale::Lang::gb   ← Global Base data (default/fallback)
├── AmberDB::Locale::Lang::en   ← English data
├── AmberDB::Locale::Lang::tr   ← Turkish data
├── AmberDB::Locale::Lang::de   ← German data
├── AmberDB::Locale::Lang::fr   ← French data
├── AmberDB::Locale::Lang::es   ← Spanish data
├── AmberDB::Locale::Lang::ru   ← Russian data
├── AmberDB::Locale::Lang::az   ← Azerbaijani data
├── AmberDB::Locale::Lang::ar   ← Arabic data
├── AmberDB::Locale::Lang::ja   ← Japanese data
└── AmberDB::Locale::Currency   ← ISO 4217 universal currency data
```

Each `Lang::*` module contains only a single subroutine called `data()` and returns a hash-ref. **No logic is included.**

---

## 3. Object Construction (Constructor)

```perl
use AmberDB::Locale;

# 1) Named-param API (recommended)
my $lang = AmberDB::Locale->new(language => "tr");

# 2) Hashref API
my $lang = AmberDB::Locale->new({ language => "de" });

# 3) Positional string API
my $lang = AmberDB::Locale->new("fr");

# 4) No args → defaults to "gb" (Global Base)
my $lang = AmberDB::Locale->new();
```

### Internal behaviors

- **Caching:** A second `new()` call for the same language returns the existing instance (singleton-like).
- **Alias support:** Labels like `"global"`, `"gl"`, `"turkish"`, `"tr_tr"`, `"tr-tr"` are automatically mapped to canonical codes.
- **Fallback:** If an unknown language is requested, a `cluck` warning is emitted and it falls back to `gb`.
- **Collator:** Attempts to load `Unicode::Collate::Locale`; if it fails, falls back to base `Unicode::Collate`, and if that's also unavailable, uses a custom `sort_map` Schwartzian transform.

### AmberDB integration

```perl
# Language is automatically pulled from cfg
my $db = AmberDB->new(cfg => { language => "tr" });
$db->uc("ığdır");   # works via inheritance: IĞDIR
```

---

## 4. Language Data Structure (`data()` Hash-Ref)

Complete schema of the structure returned by each language module:

```perl
{
    uc_map          => { },   # Character mapping applied before uc()
    lc_map          => { },   # Character mapping applied before lc()
    sort_map        => { },   # Custom sort weights (if no collator)
    alphabet_chars  => "...",  # Safe character class for normalize()
    accent_map      => { },   # normalize() accent → local equivalent
    ascii_map       => { },   # to_ascii() pre-mapping before NFD
    numbers         => { },   # num2text number words
    html_entities   => { },   # Locale-specific extra HTML entities
    months          => [ ],   # 12-element month names
    days            => [ ],   # 7-element day names (Sunday → Saturday)
    number_format   => { },   # Decimal/grouping separator settings
    default_currency    => "",
    currency_position   => "prefix|suffix",
    currency_space      => 0|1,
    date_format     => { },   # short, medium, long, full, time, datetime
    plural_rule     => "...", # CLDR plural rule expression
}
```

---

## 5. Public API - Method Reference

### 5.1 Case Conversions

#### `uc($string)` - Convert to uppercase

```perl
my $tr = AmberDB::Locale->new(language => "tr");
$tr->uc("ığdır");       # "IĞDIR"
$tr->uc("istanbul");    # "İSTANBUL"  (i → İ, Turkish rule)

my $de = AmberDB::Locale->new(language => "de");
$de->uc("straße");      # "STRASSE"   (ß → SS)
```

> **Turkish detail:** The mapping `'i' => "\x{130}"` inside `uc_map` is applied **before** Perl's `CORE::uc()` call. This ensures the `i → İ` conversion is done correctly.

#### `lc($string)` - Convert to lowercase

```perl



( run in 0.497 second using v1.01-cache-2.11-cpan-4716db65a44 )