How to assign object to ref - nim-lang

This code fails to compile:
var s: ref string = nil
s = ref "hi"
echo s
The error is (2, 9) Error: type expected, but got: "hi". I've tried putting ref and ptr in front and back of the string, tried to find some example in the documentation, but failed.

var s: ref string
new(s)
s[] = "hi"
echo s[]
Declare
Allocate new object
Assign to dereferenced string
Echo final string in dereferenced form
Note that echo s[] is needed because ref string does not implement $ operator, and cannot be converted to string by echo.

Not entirely sure why you want to do this. But first you need to create your ref type, then assign the value to a string. Something like this:
var s: ref string = nil
echo s.repr
new s
s[] = "hi"
echo s[]
echo s.repr
Will output something like this:
nil
hi
ref 0x7f7d4bbcf050 --> 0x7f7d4bbd2090"hi"
But as I said, not sure why you'd want this. Strings are already a reference type. As long as you pass them as mutable to a procedure you will be able to modify the underlying data:
var s: string = ""
s = "hi"
echo s
echo s.repr
proc test(x: string) =
echo x.repr
proc testM(x: var string) =
echo x.repr
x[1] = 'o'
test s
testM s
echo s
echo s.repr
Will output something like:
hi
0x7f5fc2807060"hi"
0x7f5fc2807060"hi"
0x7f5fc2807060"hi"
ho
0x7f5fc2807060"ho"

Related

How do I use a `concept` in Nim?

I'm wondering how to use a "concept" in nim (0.13). I have the following code:
type
T = concept t
t.a is string
T0 = ref object
a: string
T1 = ref object
a: string
q: string
proc echoT(t: T) : void =
echo "hello " & t.a
echoT(T0(a: "T0"))
echoT(T1(a: "T1", q: "q"))
However, the compiler complains on the first call to echoT:
t.nim(21, 6) Error: type mismatch: got (T0)
Shouldn't this work the same as replacing the echoT declaration with:
proc echoT[T](t: T): void = echo "hello " & t.a
(which does compile and run), except that, in the concept version, the constraint
t.a is string is enforced?
How do I get the compiler to recognize the use of a concept?
Your example compiles and works fine for me (Nim 0.13.0). Is it possible you made a typo in your source file?

Cannot convert value of type 'Range<Int>' to expected argument type 'Range<Index>' (aka 'Range<String.CharacterView.Index>')

I have a string here, which I am trying to substring.
let desc = "Hello world. Hello World."
var stringRange = 1..<5
desc.substringWithRange(stringRange)
However Swift gives me an error with this. What have I done wrong? I am using the new notation of the stringRange because it doesn't let me use the old one.
The Range you have created does not have the correct type, it is inferred to be an Int. You need to create the range from the string itself:
let desc = "Hello world. Hello World."
let stringRange = desc.startIndex..<desc.startIndex.advancedBy(5)
let sub = desc[stringRange]
It's slightly more complex with String. Alternatively, go back to NSString and NSRange:
let range = NSMakeRange(0, 5)
let sub2 = (desc as NSString).substringWithRange(range)
Your 1..<5 is from type Range<Int>, while the method substringWithRange expects a value from type Range<Index>
let desc = "Hello world. Hello World."
var dd = desc.substringWithRange(desc.startIndex..<desc.startIndex.advancedBy(5))
You may apply advanceBy to the desc.startIndex as well

Converting a seq[char] to string

I'm in a situation where I have a seq[char], like so:
import sequtils
var s: seq[char] = toSeq("abc".items)
What's the best way to convert s back into a string (i.e. "abc")? Stringifying with $ seems to give "#[a, b, c]", which is not what I want.
The most efficient way is to write a procedure of your own.
import sequtils
var s = toSeq("abc".items)
proc toString(str: seq[char]): string =
result = newStringOfCap(len(str))
for ch in str:
add(result, ch)
echo toString(s)
import sequtils, strutils
var s: seq[char] = toSeq("abc".items)
echo(s.mapIt(string, $it).join)
Join is only for seq[string], so you'll have to map it to strings first.
You could also try using a cast:
var s: seq[char] = #['A', 'b', 'C']
var t: string = cast[string](s)
# below to show that everything (also resizing) still works:
echo t
t.add('d')
doAssert t.len == 4
echo t
for x in 1..100:
t.add('x')
echo t.len
echo t

Swift String, Character Concatenation Plus Assignment

I'm getting this with Xcode 6.1(6A1046a), as I did with 6.0:
var dog:String = "Dog"
let plural:Character = "s"
let dogs:String = dog.append(plural)
Playground reports:
Playground execution failed: :29:23: error: cannot invoke
'append' with an argument of type 'Character' let dogs:String =
dog.append(plural)
Why can I not do this, although this is fine:
dog.append(plural)
The error message is misleading, but the problem is that
mutating func append(c: Character)
modifies its receiver and returns Void (aka () aka "nothing"):
var dog:String = "Dog"
let plural:Character = "s"
dog.append(plural) // now dog contains the string "Dogs"
With
let dogs = dog + String(plural)
you can create a new string instead.
Remark: You could actually assign
let foo = dog.append(plural)
but that would assign the empty tuple () to foo (which is not what you intend).
The error message in your code is caused by the fact that you cannot assign ()
to a String variable.

How do I enumerate all the defined variables in a groovy script

I have a groovy script with an unknown number of variables in context at runtime, how do I find them all and print the name and value of each?
Well, if you're using a simple script (where you don't use the "def" keyword), the variables you define will be stored in the binding and you can get at them like this:
foo = "abc"
bar = "def"
if (true) {
baz = "ghi"
this.binding.variables.each {k,v -> println "$k = $v"}
}
Prints:
foo = abc
baz = ghi
args = {}
bar = def
I'm not aware of an easy way to enumerate through the variables defined with the "def" keyword, but I'll be watching this question with interest to see if someone else knows how.
Actually, Ted's answer will also work for 'def'ed variables.
def foo = "abc"
def bar = "def"
if (true) {
baz = "ghi"
this.binding.variables.each {k,v -> println "$k = $v"}
}
yields
baz = ghi
__ = [null, null, null]
foo = abc
_ = null
bar = def
I'm not sure what the _-variables signify, but I'm sure you can work around them.
Groovy Object contains method - dump()
https://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Object.html
String dump()
Generates a detailed dump string of an object showing its class, hashCode and fields.
Example:
class MyClass {
def foo = "abc"
def bar = "def"
}
println(new MyClass().dump())
stdout: <MyClass#1fa268de foo=abc bar=def>

Resources