ClassDefinition_step2 - gama-platform/gama GitHub Wiki

Attributes and Actions

Dot Notation

Reading an attribute

counter c <- counter(label: "clicks", value: 0, step: 1);
int val <- c.value;  // val = 0

Writing an attribute

c.value <- 42;    // direct write
c.step <- 5;      // change the step size

Note: Objects are NOT agents. They have no reflex, no schedule, no population. All state changes must be driven by explicit calls from the outside — either direct attribute assignment or via actions.

Calling Actions

Actions that return a value

int val <- c.increment();  // val = 43 (value becomes 45 after +step=5*1=5... wait, step is 5, so increment adds 5)
// After c.value <- 42, c.increment() adds step(5) → value becomes 47

Actions that modify state

c.reset();       // sets value back to 0, no meaningful return
write c.to_string();  // clicks = 0  (step=5)

Chained Action Calls

Use the return value directly as an operand:

bool big <- c.increment() > 50;
// This calls increment() which returns the new value,
// then compares it to 50 — all in one expression.

Passing Objects as Arguments

Actions can take object arguments — the type is declared in the signature:

class counter {
	int value <- 0;
	
	bool same_value_as(counter other) {
		return value = other.value;
	}
}

counter c <- counter(value: 10);
counter d <- counter(value: 20);
c.same_value_as(d);        // false after both have value 10 → true after reset

Object Comparison

Two objects of the same type can be compared using the = operator. In the counter example, same_value_as checks if the value attributes match.

Aggregate Operations Over Lists of Objects

Objects stored in lists can be processed using GAML's collection operations:

list<counter> counters <- [];
loop i from: 1 to: 5 {
	counters <+ counter(label: "c" + i, value: rnd(10), step: 1);
}

// Collect an attribute from every object
write "Counters: " + (counters collect each.to_string());

// Compute aggregate values
int max_val <- max(counters collect each.value);
float mean_val <- mean(counters collect each.value);
write "Max value: " + max_val;
write "Mean value: " + (mean_val with_precision 2);

// Iterate and mutate
loop cnt over: counters {
	if float(cnt.value) < mean_val {
		cnt.increment();
	}
}

Example: Bank Account

class bank_account {
	string owner <- "unknown";
	float balance <- 0.0;
	float min_balance <- 0.0;
	
	bool deposit(float amount) {
		if amount <= 0.0 { return false; }
		balance <- balance + amount;
		return true;
	}
	
	bool withdraw(float amount) {
		if amount <= 0.0 { return false; }
		if balance - amount < min_balance { return false; }
		balance <- balance - amount;
		return true;
	}
	
	bool transfer(float amount, bank_account target) {
		if withdraw(amount) {
			bool ok <- target.deposit(amount);
			return ok;
		}
		return false;
	}
	
	string to_string() {
		return owner + ": balance=" + (balance with_precision 2);
	}
}

global {
	init {
		bank_account alice <- bank_account(owner: "Alice", balance: 500.0);
		bank_account bob   <- bank_account(owner: "Bob",   balance:  50.0);
		
		bool ok1 <- alice.deposit(200.0);        // true
		bool ok2 <- alice.withdraw(100.0);       // true
		bool ok4 <- alice.transfer(300.0, bob);  // true (Alice:200, Bob:350)
		
		bool ok5 <- alice.transfer(999.0, bob);  // false (insufficient funds)
	}
}

Key Takeaways

Operation Syntax
Read attribute obj.attr
Write attribute obj.attr <- value
Call action obj.action(args)
Chain action results bool ok <- obj.action() > threshold
Pass object as argument obj.method(other_object)
Collect attribute list collect each.attr
⚠️ **GitHub.com Fallback** ⚠️