# Ruby

## 1. Add Dependency

[![](https://img.shields.io/gem/v/hackle-ruby-sdk)](https://rubygems.org/gems/hackle-ruby-sdk)

```shell
gem install hackle-ruby-sdk -v '~> 2.0.0'
```

## 2. Initialize SDK

{% hint style="danger" %}
Hackle::Client must be a singleton.

`Hackle::Client` manages state internally to distribute A/B test and Feature Flag results without making network calls. This requires additional resources. Instead of creating a new instance for every request, it must be managed as a single instance throughout the application lifecycle.
{% endhint %}

To use the SDK, you need to initialize `Hackle::Client`.

* `Hackle::Client` is the class that provides methods for using the SDK's features.
* You can find your SDK Key in the [SDK Integration Info](https://dashboard.hackle.io/config/sdk-setting) section of the Hackle Dashboard.

```ruby
require 'hackle-ruby-sdk'

hackle_client = Hackle::Client.create(sdk_key: 'YOUR_SERVER_SDK_KEY')
```

### Using the SDK with Rails

In Rails, initialize and shut down the SDK as follows.

```ruby
# config/initializers/hackle_client.rb

$hackle_client = Hackle::Client.create(sdk_key: 'YOUR_SERVER_SDK_KEY')
at_exit { $hackle_client.close }
```

### Cluster Mode

When the application starts, the SDK creates multiple threads.\
Each thread has an infinite loop in the background that batch-processes and delivers events, and fetches A/B test information.

When using the SDK in a web server that spawns multiple child processes (e.g., Puma, Unicorn / workers > 0), the application server creates child processes but does not recreate threads that exist in the parent process.

Therefore, when running in cluster mode with Unicorn, Puma, etc., you need to create an additional SDK instance after child processes or workers are spawned.

#### Unicorn

```ruby
# config/unicorn.rb

after_fork do |server, worker|
  $hackle_client = Hackle::Client.create(sdk_key: 'YOUR_SERVER_SDK_KEY')
end
```

#### Puma

```ruby
# config/puma.rb

on_worker_boot do
  $hackle_client = Hackle::Client.create(sdk_key: 'YOUR_SERVER_SDK_KEY')
end
```

***

## 3. Event Tracking

You can send user actions as events. Tracked events are used for A/B test analysis, data analytics, and more.\
For example, if a user makes a purchase, you can track the event as shown below.

```ruby
require 'hackle-ruby-sdk'

# Send a 'purchase' event triggered by a user with device identifier 'ae2182e0'

user = Hackle::User.builder
                   .device_id('ae2182e0')
                   .build

event = Hackle::Event.builder('purchase')
                     .property('amount', 4200)
                     .property('pay_method', 'CARD')
                     .property('is_discount', false)
                     .property('product_ids', [42, 43])
                     .build

hackle_client.track(event, user)
```

#### Verifying Tracked Events

You can check tracked events in the [Event Management](https://dashboard.hackle.io/event-management) menu on the Dashboard. It generally takes \~60 seconds for events to appear on the Dashboard after being tracked.

***

## 4. A/B Test

Distribute users into variations and implement logic based on the assigned variation to run A/B Tests. Call `variation` with the Experiment Key to receive the distribution result.

[Experiment Key](/en/development-guide/sdk/get-your-key.md): A unique number assigned to each A/B test. It is automatically issued when you create an A/B test.

{% hint style="warning" %}
Cohort targeting is not supported in Server SDKs. If targeting includes a cohort, perform the test using a Client SDK.
{% endhint %}

```ruby
require 'hackle-ruby-sdk'

# Determines which variation to show to a user with identifier 'ae2182e0'
# in the A/B test with experiment key 42.
# Returns variation A if a decision cannot be made.

user = Hackle::User.builder
                   .device_id('ae2182e0')
                   .build

variation = hackle_client.variation(42, user)

if variation == 'A'
  # Group A logic
elsif variation == 'B'
  # Group B logic
end
```

***

## 5. Feature Flag

A Feature Flag has an on state and an off state. Implement different logic based on the state to use Feature Flags. Call `is_feature_on` with the Feature Key to receive the on/off status.

\[Feature Key]\(../../기능 플래그/ff-manage/ff-detail.md): A unique number assigned to each Feature Flag. It is automatically issued when you create a Feature Flag.

```ruby
require 'hackle-ruby-sdk'

# Determines the feature on/off status for a user with identifier 'ae2182e0'
# for the Feature Flag with feature key 42.
# Returns false (off state) if a decision cannot be made.

user = Hackle::User.builder
                   .device_id('ae2182e0')
                   .build

feature_on = hackle_client.is_feature_on(42, user)

if feature_on
  # ON feature
else
  # OFF feature
end
```

***

## 6. Shutdown

When the application shuts down, call `hackle_client.close` to shut down the `hackle_client`.\
This releases the resources in use by the client and sends any remaining events.

{% hint style="danger" %}
If the application exits without calling `hackle_client.close`, events may be lost.
{% endhint %}

```ruby
hackle_client.close
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/en/development-guide/ruby.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
