hi, i'm new to nim and i'm trying to make an object have default values
type
Foo = object
bar: int # = 42
value: float # = 3.2
var foo = Foo() # bar is set to 0 and value is 0.0
echo foo
i would like to make Foo's bar have a default value of 42 and value default to 3.2There are no default values in object declaration. Usual way to do this is with a newFoo proc.
proc newFoo(): Foo =
Foo(bar: 42, value = 3.2)
There are no default values
But there are rumors that we may get them for Nim > 1.0
Usual way to do this is with a newFoo proc.
I think this might be more versatile:
type
Foo = object
bar: int
value: float
proc initFoo(bar = 42, val = 3.2): Foo =
Foo(bar: bar, value: val)
var foo1 = initFoo()
var foo2 = initFoo(val = 9.9)
var foo3 = initFoo(21, 17.34)
echo foo1 # => (bar: 42, value: 3.2)
echo foo2 # => (bar: 42, value: 9.9)
echo foo3 # => (bar: 21, value: 17.34)
new_xxx is more flexible, yet having default parameters for object and shortcut notation for object initialisation, shortening Obj(some_name: some_name) as Obj(some_name) would still be useful.
Example:
type
CrawlerRef*[J] = ref object
id: string
version: int
jobs: seq[J]
data_dir: string
job_states: JobStates
saved_at_sec: int64
last_saved: Option[JobStates]
job_i: int # = -1
How the initialisation looks now
proc new_crawler*[J: Job](
id: string,
version: int,
jobs: seq[J],
data_dir: string,
): CrawlerRef[J] =
CrawlerRef[J](
id: id,
version: version,
jobs: jobs,
data_dir: data_dir,
job_states: job_states,
job_i: -1
)
How it could look with defaults and shortcuts
proc new_crawler*[J: Job](
id: string,
version: int,
jobs: seq[J],
data_dir: string,
): CrawlerRef[J] =
CrawlerRef[J](id, version, jobs, data_dir, job_states)
For the record, there's a convention for how to name the initializer proc (or func). Procs that return a value object start with init and procs that return a reference object start with new. The standard library uses this convention almost throughout (in the parts I used so far).
I'm not totally glad with the naming distinction for value/ref objects myself, but not following the convention may be confusing for readers of your code.
I actually have a macro which is similar to that, allowing multiple constructors and calling logic after the creation for anyting the user needs. Below is a small sample.
import constructor
type
Awbject = object
awesome : float
beautiful : string
coolInt : int
Awbject.construct(true):
beautiful: "This is indeed"
awesome: 1.1
_:
#[
Can call code after created.
'result' is where the constructed variable is stored.
]#
echo "Heh"
initAwbject()
Hmm, but I use the new prefix for the reference object - proc new_crawler(...): CrawlerRef where's the mistake?
No mistake. :-) I only wanted to make sure you knew that the new prefix wasn't "universal" for all initializers.
I thought you had written something in this thread that suggested a misunderstanding. But I don't see it now. Maybe this was in another thread. Anyway, I bet there are other people reading the forum who could benefit from my post. :-)