<jhass>
Does Crystal follow Rubys object model? In particular, are "class methods" (class Foo; def self.bar; end; end;) singleton instance methods on the Class object that's assigned to Foo? And if so, is self inside a class definition that Class object?
<asterite>
It’s no exactly the same object model
<asterite>
Right now if you do `class Foo; puts self; end` you will get an error “there's no self in this scope”
<asterite>
which is actually not true, but we need to implement it
<asterite>
The question is: what do you want to do?
<asterite>
but we chose that to behave in a different way than Ruby
<asterite>
In our case, that initializes the instance varibale of any instance of that class
<asterite>
I don’t find singleton classes instance variables that useful
<asterite>
and then you have @@vars
<asterite>
I think it’s like, two ways to do almost the same thing
<jhass>
@@vars are dangerous in ruby because they are shared across the ancestry chain
<jhass>
that is class Foo; @@foo = :foo; def foo; @@foo; end; end; class Bar < Foo; @@foo = :bar; end; Foo.new.foo #=> :bar
<asterite>
In Crystal (right now), @@vars are not shared across the ancestry chain
<asterite>
The truth is, we didn’t model a lot of the singleton class stuff
<asterite>
so we might need to think it further
<jhass>
hm, I never was a fan of class level instance variable initialization, I even avoid it in Java where the separation is quite clear
<asterite>
But for me, it’s unnecessarily complicated in Ruby
<jhass>
but might be taste
<asterite>
You mean, what we just did with @x = 0 ?
<asterite>
Is that what you don’t like?
<jhass>
yes, I prefer initialization to happen in the constructor
<jhass>
makes it clearer that it happens on allocation
<asterite>
Yes, that’s true
<asterite>
However, we found that in Crystal it’s useful to be able to initialize it outside the construct
<asterite>
Imagine you want to reopen a class and add an instance variable
<jhass>
and singleton classes aren't that hard, it's a dynamic transparent parent between the object and it's class, so you can think about it like class Foo; end; foo.class #=> AnonymousClass < Foo
<asterite>
In Crystal there’s this rule: if an instance variable doesn’t appear inside an “initialize”, it is considered nilable
<jhass>
that singleton classes are allocated and inserted on first access is one of the weird parts, but actually an implementation detail
<asterite>
so when you want to reopen a class and add an instance variable...
<asterite>
and you don’t want it to be nilable (like, always Int32)
<asterite>
and you don’t want to copy/paste the initialize (or just use alias_method, something we don’t have and it’s ugly)
<asterite>
then you can just initialize the instance variable to something, and that’s it
<asterite>
It’s also good if subclasses don’t invoke super, but you still want to initialize an instance variable regardless of “initialize” being called
<jhass>
but okay, I guessed there was a reason, just wanted to know ;)
<jhass>
it's actually a common mistake for ruby beginners, expecting it to work that way
<jhass>
so that might be good to do
<asterite>
Right now classes are not something that are “alive” when you run your program… like, they don’t have instance variables and so on, but I guess eventually they will be like that (or maybe)
<jhass>
yes, one of the interesting aspects of building DSLs in ruby is to be able to do something like Class.new { extend DSLMethods; include OtherStuff }.instance_exec(&block).new.do_stuff;, RSpec for example does that a lot
<jhass>
(transforms describe blocks into classes and it blocks to methods that way, iirc)
<asterite>
Yes… that’s too much magic which, I’m afraid, might not be possible to do in Crystal
<asterite>
it requires too much dynamism
<asterite>
I also wonder if rspec is slower than testunit because of that dynamism and all of that happening at runtime
e_dub has joined #crystal-lang
<jhass>
it happens at loadtime, not during test execution
<asterite>
what’s the difference?
<asterite>
when you write `rspec` and the console, you have to wait for all that class definition to happen
<jhass>
the bootup time might be slower, but running the tests is not affected, which makes it possible to have benefits through guard and the like
<asterite>
I see
<asterite>
but then you have to use a separate tool, which complicates things
<asterite>
(btw, I really like and use rspec a lot)
<asterite>
maybe when we have more powerful macros (ones that can receive blocks) we can generate classes and code like that at compile-time, instead of runtime
<jhass>
I guess it's just hard to switch thinking when the language already feels so familiar :P
<asterite>
Yes… but we inevitably have to make some compromise decisions if we want to retain good performance and static type checks
<jhass>
in the tests the code in the run stuff is already compiled at runtime, right? So that uses some kind of Just in time compiler? What about polishing that up and making a nice API on top of it as a long term goal?
<asterite>
btw, we can just choose another syntax instead of “@x = 0” for initializing instance variables…
<jhass>
yes, I'm thinking about that too, just nothing too clear that came to my mind yet
Rylee has joined #crystal-lang
<asterite>
Yes, we use a llvm’s jit, but it’s hard to use that for macros
<asterite>
there are some issues
<jhass>
what about something like being able to embed and call the compiler and the exec to the result?
<alex-guenther>
how would I define an array of hashes of string => string? like this? @result_rows = Array(Hash(String, String)).new
<asterite>
Yes
<asterite>
Or @result_rows = [] of Hash(String, String)
<asterite>
We could also introduce some syntax sugar for arrays and hashes types
<asterite>
something like: [] of (String => String)
<asterite>
or [] of String[], to denote an array of array of string
<asterite>
but for now Hash(String, String) works
<alex-guenther>
ok thanks
<asterite>
how’s the sqlite3 wrapper going? the other day you had a question but I was busy to answer
<alex-guenther>
so I was playing with sqlite and the LibSqlite3 part seems to be the easyer part, but the Object wrapper thing is more challenging
<alex-guenther>
I've got a basic open/exec/close and some of the prepared statement stuff kind of working, no real error handling yet
<asterite>
cool :)
<asterite>
what’s that Object wrapper?
<asterite>
and how did you execute a query without us having good support for closures?
<alex-guenther>
I've been looking at the ruby sqlite gem and tryed to make something like they have: Database.new(file) { |db| db.exec('query').each { |row| puts row } }
<alex-guenther>
I'll better paste the code to a gist
<alex-guenther>
libs sqlite3 lib_sqlite3.cr means libs/sqlite3/lib_sqlite3.cr gist doesn't let me post filenames with slashes
<asterite>
I get “undefined method '<<' for Nil” in @result_rows << row
<asterite>
You too?
<alex-guenther>
yes
<alex-guenther>
the problem here is I assign an empty array to @result_rows in the exec method but use it with << in the exec_callback
<asterite>
yes
<asterite>
What you can do is do: result_rows = @result_rows.not_nil!
<asterite>
and then work with result_rows
<asterite>
that is, assert that it is not nil
<asterite>
and continue working with a variable that is guaranteed to not be nil
<alex-guenther>
awesome
<asterite>
in the same way, you can do: result_rows = @result_rows = Array(Hash(String, String)).new
<asterite>
and return result_rows in exec, so there you can guarantee it’s not nil
<asterite>
or you can use “whatever” to pass there the result_rows
<asterite>
(maybe, I’m not sure)
<alex-guenther>
the callback should return 0 as a success sign, but maybe I can pass it as whatever
<asterite>
I got it to compile, but the linker can’t find sqlite3_close_v2
<asterite>
but then I changed it to sqlite3_close, compiled, ran, and a lot of info appears on the screen :)
<asterite>
apparently it’s doing something :)
<alex-guenther>
hmm one thing I realized last weekend is that Arch Linux (what I use) is really weird. They do some interesting stuff ...
<alex-guenther>
they use complete different readline headers than anybody else
<alex-guenther>
which version of sqlite3 do you have?
<asterite>
3.8.4.3
<alex-guenther>
I have 3.8.4.3-2
<alex-guenther>
so there should be no difference ...
Excurio has joined #crystal-lang
<asterite>
Ah, but homebrew tells me: Mac OS X already provides this software and installing another version in parallel can cause all kinds of trouble.
<asterite>
:)
<asterite>
maybe that’s it
<asterite>
nevermind, later i’ll fix my system for that
<alex-guenther>
I used homebrew with my last job, it's nice
<asterite>
Good. Yes, I can see that function in my sqlite3 header, but apparently it’s using the one that comes with mac osx
<asterite>
so it’s good that you use sqlite3_close_v2 :)
<alex-guenther>
Using sqlite3 has some constraints. So wrapping prepared statements in objects that don't let you execute a disposed statement should be helpful.
<asterite>
how do you know if a statement is disposed?
<alex-guenther>
what do you suggest would be the best to do with my code, should I clean it up and make a pull request? Should I stay wit that structure or reorganize the files?
<alex-guenther>
It's all bookeeping of what you do with your objects. So finalizing a statement means you'r not longer using it.
<asterite>
Yes, you can clean it up and make a pull request. It would be nice if you included some specs, that would query an in-memory db and so on
<asterite>
We can always improve it and clean it up further
<alex-guenther>
I'll try to write some this weekend. I think I'll be bussy with other stuff till the end wo month afterwards, so it would be nice to get it 'done'.
<asterite>
it’s ok, you can just send a pull request and we’ll accept it and add tests later
<asterite>
Kent Beck will look bad at us, but DHH will be ok with that decision, I guess...
<alex-guenther>
I know what you'r talking about :)
<alex-guenther>
I used only UTF-8 with sqlite, would somebody use UTF-16 with crystal? Do we need the UTF-16 methods?
<waj>
Currently strings in Crystal are always represented as UTF-8
nekron has joined #crystal-lang
CraigBuchek has joined #crystal-lang
<asterite>
so I guess we don’t need the UTF-16 methods for now