00:02
<
asterite >
Um, that last one doesn't compile, nevermin
00:03
travis-ci has joined #crystal-lang
00:03
<
travis-ci >
manastech/crystal#1868 (master - 5fe6294 : Ary Borenszweig): The build passed.
00:03
travis-ci has left #crystal-lang [#crystal-lang]
00:05
asterite has quit [Quit: Page closed]
00:16
sferik has joined #crystal-lang
00:33
zamith has quit [Ping timeout: 255 seconds]
00:34
zamith has joined #crystal-lang
00:36
sferik has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
00:36
filer has quit [Quit: No Ping reply in 180 seconds.]
00:37
filer has joined #crystal-lang
00:44
sferik has joined #crystal-lang
00:48
bcardiff has joined #crystal-lang
01:11
leafybasil has joined #crystal-lang
01:14
leafybasil has quit [Remote host closed the connection]
01:15
leafybasil has joined #crystal-lang
01:21
leafybasil has quit [Remote host closed the connection]
01:24
sferik has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
01:26
zamith has quit [Quit: Be back later ...]
02:00
<
jhass >
epitron: did you ever edit your makepkg.conf? If so, any flags changed from the defaults?
02:23
CeBot has quit [Quit: Crystal]
02:23
CeBot has joined #crystal-lang
03:14
<
epitron >
jhass: i don't think i edited my makepkg.conf -- it looks standard
03:16
<
epitron >
ok, so, using your crystal-git, i get that -fPIC problem building crystal-0.5.8
03:17
<
epitron >
err, sorry, i was building crystal-git
03:18
<
jhass >
I guess you get it always while building crystal
03:18
<
jhass >
does the package I linked let you run the crystal command though?
03:19
<
epitron >
~/opt/crystal-git-0.5.8.r112.g5fe6294-1-x86_64.pkg/usr/share/doc/crystal/samples $ crystal tree.cr
03:19
<
epitron >
Error while requiring "prelude": can't find file 'prelude'
03:19
<
epitron >
oh wait, this is an arch package
03:19
<
epitron >
lemme install it
03:21
<
epitron >
$ crystal tree.cr
03:21
<
epitron >
/usr/bin/ld: .crystal//home/epi/opt/crystal-git-0.5.8.r112.g5fe6294-1-x86_64.pkg/usr/share/doc/crystal/samples/tree.cr/main.o: relocation R_X86_64_32S against `*GC::malloc<UInt32>:Pointer(Void)' can not be used when making a shared object; recompile with -fPIC
03:21
<
jhass >
I feared so
03:21
<
jhass >
so what's llvm-cofnig --host-target ?
03:22
<
epitron >
x86_64-unknown-linux-gnu
03:22
<
jhass >
same as mine :/
03:22
<
epitron >
so, why is main.o being build without -fPIC?
03:22
<
jhass >
intel or amd cpu?
03:22
<
epitron >
Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
03:22
<
jhass >
we basically have identical setups :/
03:23
<
epitron >
let me make sure i'm not using a weird llvm
03:23
<
jhass >
dunno, we literally just call the LLVM api with it's defaults
03:23
<
jhass >
it's very similar to like "clang foo.c"
03:23
<
epitron >
oh, so llvm is building the .o files?
03:23
<
jhass >
but pretty sure
03:24
<
epitron >
it is calling `cc` here
03:24
<
jhass >
so, I have an i7, but if that would be what makes the difference... :/
03:24
<
epitron >
here's the full error
03:25
<
jhass >
mmh, I have CC and CXX set to clang/clang++
03:25
<
jhass >
the environment variables
03:25
<
epitron >
maybe i should try that
03:25
<
jhass >
my /usr/bin/cc is symlinked to gcc though
03:26
<
epitron >
$ which cc
03:26
<
epitron >
/usr/lib/hardening-wrapper/bin/cc
03:26
<
epitron >
hardening, eh? :)
03:26
<
epitron >
looks like i installed some security shit
03:26
<
jhass >
that sounds... interesting
03:27
<
epitron >
$ paci hardening-wrapper
03:27
<
epitron >
Name : hardening-wrapper
03:27
gr33n7007h has quit [Ping timeout: 244 seconds]
03:27
<
epitron >
Version : 8-1
03:27
<
epitron >
Description : Wrapper scripts for building hardened executables by default
03:27
<
epitron >
Architecture : x86_64
03:27
<
epitron >
ok, i'm taking that out of my path
03:28
<
jhass >
great how the repo actually describes what it does and why :/
03:28
<
epitron >
it works!
03:28
<
epitron >
it's just all those buffer overflow workarounds
03:29
<
epitron >
it's wrapping everything, including clang{,++}
03:29
<
jhass >
care to experiment a bit? I got an idea
03:29
<
jhass >
do you have local git clone?
03:30
<
epitron >
oh man, this is exciting
03:30
<
epitron >
i just played 2048 :D
03:30
<
epitron >
i have a clone, yes
03:30
<
jhass >
okay, can you try adding -fPIC to the line I linked above?
03:31
<
jhass >
and then run make inside the repo
03:31
<
jhass >
after reenabling the hardening stuff that is
03:32
<
epitron >
i added it to the code, but it didn't have -fPIC in the cc output
03:33
<
epitron >
Error: execution of command failed with code: 1: `cc -o /tmp/crystal-run.Ub8D4o .crystal//home/epi/src/crystal/src/ecr/process.cr/main.o -lpcre -lgc -lpthread -lunwind`
03:33
<
jhass >
oh, yes, my bad
03:33
<
epitron >
do i have to rebuild it?
03:33
<
epitron >
without hardening?
03:33
<
jhass >
and then with hardening do bin/crystal samples/whatever.cr
03:33
gr33n7007h has joined #crystal-lang
03:33
gr33n7007h has joined #crystal-lang
03:33
gr33n7007h has quit [Changing host]
03:34
<
jhass >
bin/crystal makes sure that the one built by make is used and that the local src/ get required instead of the globally installed ones
03:34
<
epitron >
whoa, that was fast
03:35
<
epitron >
ok, trying
03:36
<
epitron >
how do i install this? should i just put .build/crystal in ~/bin?
03:36
<
jhass >
so it works?
03:37
<
epitron >
it built it with the -fPIC option in the code
03:37
<
epitron >
but i haven't tried to build w/ hardening scripts
03:37
<
epitron >
because i only have one git checkout
03:37
<
epitron >
and i don't wanna wipe out the -fPIC binary :)
03:37
<
jhass >
as said, just do bin/crystal samples/2048.cr
03:37
<
jhass >
the bin/crystal wrapper makes sure to use the locally compiled one
03:38
<
jhass >
it's in the output though?
03:38
<
epitron >
oh, it's not :(
03:38
<
jhass >
did it say "Using .build/crystal"?
03:39
<
epitron >
i removed your package
03:39
<
epitron >
the only crystal is that one
03:40
<
jhass >
line 209 has another one :)
03:40
<
epitron >
yeah, i just added that :)
03:40
<
epitron >
rebuildingggg
03:40
<
epitron >
ok, same bug, BUT -fPIC is there
03:41
<
epitron >
i guess i'll just shut off this hardening stuff
03:42
<
jhass >
so it's really because llvm emits the o files without the flag I guess
03:42
<
jhass >
the cc call just links
03:42
<
epitron >
that makes snse
03:42
<
jhass >
I guess I'll take a look at what that thing actually does and whether the llvm api has something
03:43
<
epitron >
i'm guessing it's a defense against buffer overflows knowing where to jump
03:43
<
epitron >
random memory layout
03:45
<
jhass >
I could imagine it makes ROP chaines more portable
03:45
<
epitron >
that's what -fPIE does
03:50
<
epitron >
"it requires the executable be built with -fPIE for any .o files that are linked at the end with -pie."
03:50
<
epitron >
i'm going to add PIE :)
03:51
<
epitron >
i guess i've been using unhardened executables for 30 years
03:51
<
epitron >
why start now, right?
03:52
<
jhass >
mmh, I found the API method to get the relocation model, but none to set it yet
03:56
<
epitron >
Reloc::PIC_
03:56
<
epitron >
Reloc::DynamicNoPIC
03:56
<
epitron >
Reloc::Static
03:57
<
jhass >
thing is I don't see any engine builder stuff in our bindings
03:57
sferik has joined #crystal-lang
03:58
<
epitron >
good old enginebuilderfactoryadapters
03:58
<
jhass >
well, we use the C API anyway, so gotta find it there first
03:58
* jhass
hates doxygen
03:59
<
epitron >
i guess that makes sense, since it's all crystal
03:59
shama has joined #crystal-lang
03:59
<
epitron >
does C++ have some kind of OOP binding generation stuff?
03:59
<
epitron >
like, if i wanted to make ruby OOP bindings to some C++ lib?
04:00
<
jhass >
mmh, no idea
04:00
<
epitron >
looks like SWIG is still being maintained
04:01
<
jhass >
I guess if we would allow what symbols C++ generates as function names in C bindings, that might actually work
04:01
<
jhass >
it's just neither nice to write not use I guess
04:02
<
jhass >
C API is just much simpler
04:02
<
epitron >
that would be nasty
04:02
<
epitron >
crystal could support C++ names though
04:02
<
epitron >
and convert those to gross-names
04:03
<
epitron >
i bet there are people out there who know a lot about wrapping/binding C++ things in OOP ways
04:04
<
epitron >
if i run across one, i'll tell you :)
04:04
<
jhass >
there was somebody parsing .h files to generate bindings already
04:04
<
jhass >
more PoC state, but let me find the repo
04:08
<
jhass >
never tried those though
04:08
<
jhass >
so don't know how well they work
04:15
<
epitron >
hmm... i wonder if it would be possible to make a REPL
04:15
<
epitron >
similar to how julia does it
04:16
<
jhass >
REPL is kinda hard in a compiled language
04:16
<
jhass >
you got crystal eval for quick stuff
04:16
<
epitron >
julia uses LLVM too though
04:16
<
jhass >
>> "and me"
04:16
<
CeBot >
jhass: "and me"
04:16
<
epitron >
i mean, linking isn't necessary if you just wanna run some code
04:16
<
epitron >
you just jump to it
04:17
<
jhass >
yes, the dynamic analysis is the hard part
04:17
<
epitron >
the memory space should already contain all the crystal stuff
04:17
<
epitron >
oh, is that a necessary step?
04:17
<
jhass >
crystal does a ton of parsing and lexing stuff that has forward dependencies everywhere
04:17
<
jhass >
so as you can see, eval is no problem at all since you have a defiend scope
04:18
<
epitron >
what's a forward dependency?
04:18
<
jhass >
but in a repl you define stuff and then later may define something that affects it
04:18
<
epitron >
oh, okay.. so crystal doesn't have ruby's open classes?
04:19
<
jhass >
>> class Foo; def foo(x) x.to_s; end; Foo.new.foo("hi"); Foo.new.foo(1);
04:19
<
CeBot >
jhass: Syntax error in eval:7: expecting identifier 'end', not 'EOF'
04:19
<
jhass >
and that's part of what's making it harder
04:19
<
jhass >
>> class Foo; def foo(x) x.to_s; end; end; Foo.new.foo("hi"); Foo.new.foo(1);
04:19
<
jhass >
so, this code is generating two methods on demand
04:20
<
epitron >
so it's kinda like julia or psyco
04:20
<
jhass >
when you defined the class, you don't know which ones you need to generate yet
04:20
<
epitron >
generate methods on the fly
04:20
<
epitron >
based on argument type
04:20
<
jhass >
It#s probably possible, yes. Just a lot of effort
04:20
<
jhass >
and there's more important stuff for the moment ;)
04:25
<
jhass >
up for another experiment?
04:28
<
epitron >
sure, hold on
04:31
<
epitron >
conclusion: meh!
04:34
<
epitron >
this is very slick though
04:34
<
epitron >
i'm going to see how many ruby scripts i can port to it :)
04:36
<
epitron >
i love how fast the language builds too
04:37
<
epitron >
"make" seems so quick
04:37
<
jhass >
hehe, then don't run make spec
04:37
<
jhass >
but it's fast yeah
04:38
<
epitron >
haha.. egrep.cr
04:39
<
epitron >
sudoku.cr is weird
04:39
<
epitron >
it solves them all instantly, then sits around for a while chewing CPU
04:39
<
epitron >
then quits
04:40
<
epitron >
oh i see, it does it 10 times
04:41
<
jhass >
mmh, the samples weren't touched for some time
04:42
<
jhass >
2048 was my first contribution to crystal though :D
04:45
<
epitron >
this is odd -- i can't convert Time.now.to_f
04:45
<
jhass >
>> Time.now.to_f
04:45
<
CeBot >
jhass: Error in line 3: undefined method 'to_f' for Time (did you mean 'to_i'?)
04:46
<
jhass >
well, nobody added it yet ;)
04:46
<
epitron >
>> Time.now - Time.now
04:46
<
CeBot >
epitron: -00:00:00.0000010
04:46
<
epitron >
oh, that didn't work before
04:46
<
epitron >
there's no to_f on the timediff either
04:47
<
jhass >
expect quite a few holes in stdlib still, the upside is that everything is written in crystal, so filling the gaps is actually fun and asterite is very open to including stuff ;)
04:47
<
epitron >
i just need to figure out how to make sublime use ruby syntax on .cr files
04:47
<
jhass >
bottom right
04:47
<
jhass >
where it says the current syntax
04:48
<
jhass >
click on it, then on the very top
04:48
<
epitron >
View -> Syntax -> Open all with current extension as...
04:48
<
jhass >
or there ;)
04:48
<
jhass >
same menu I guess
04:49
<
epitron >
i'm so not used to building stuff
04:49
<
epitron >
pry is part of how i think now
04:49
<
epitron >
Int has .hours, .minutes, .days
05:31
<
epitron >
whoa, single quotes are for chars?
05:31
<
epitron >
why not use the ?c format?
05:33
<
jhass >
because it's ugly? :P
05:33
<
jhass >
you'll get used to after some times, in fact more and more ruby people say to always double quote too
05:35
<
epitron >
it's so... not how every other language works though
05:35
<
epitron >
i mean, needing it use a char is a pretty rare thing
05:35
<
epitron >
while porting over old ruby code probably WILL be pretty common
05:37
<
jhass >
C and Java are just two examples that handle it the same way
05:37
<
epitron >
oh yeah :(
05:37
<
epitron >
my two least favorite languages
05:38
<
epitron >
i think all the dynamic languages use '' as strings though
05:38
<
jhass >
Crystal is not a dynamic language though ;)
05:38
<
epitron >
i know, but it's based on ruby!
05:38
<
jhass >
inspired is the better point at this time ;)
05:39
<
epitron >
don't you want to maximize programmer happiness? :)
05:39
<
epitron >
btw, i'm trying to figure out how to do this --
05:39
<
epitron >
for empty hashes use '{} of KeyType => ValueType
05:39
<
epitron >
even your error messages do single quote strings ;)
05:39
<
jhass >
>> {} of String => String
05:39
<
epitron >
i tried that
05:40
<
epitron >
expecting token 'EOF', not 'end'
05:40
<
jhass >
I did fight with the single quotes too in the beginning btw
05:41
<
epitron >
i think that's a pretty annoying feature
05:41
<
jhass >
it really is just better in a compiled, performance aware language to have a char type
05:41
<
epitron >
that's fine
05:41
<
epitron >
ruby's ?c thing worked well
05:41
<
epitron >
(back when ruby still thought a char type was a good idea)
05:42
<
jhass >
?c did return an integer though
05:42
<
jhass >
and as said, I think the syntax is ugly and asterite agrees
05:42
<
epitron >
i mean, you guys are obviously going a slightly different direction
05:42
<
jhass >
?c was done because String#[] returned integers, really
05:43
<
epitron >
i just think not having single quote strings, and having them do something else, will annoy a lot of people
05:43
<
epitron >
i mean.. your error messages use single quote strings! :)
05:43
<
epitron >
it's natural to see 'x' as a string
05:43
<
epitron >
not a char
05:44
<
epitron >
cognitive ergnomics
05:44
<
jhass >
mmh, I don't think we have for?
05:44
<
jhass >
>> for x in [1, 2, 3]; print x; end
05:44
<
CeBot >
jhass: Syntax error in eval:5: expecting token 'EOF', not 'rescue'
05:45
<
epitron >
that explains it
05:46
<
jhass >
epitron: you can open an issue at github about it, so we get more people to discuss ;)
05:46
<
epitron >
lesspipe(:wrap=>true) do |less|
05:46
<
epitron >
no hash args?
05:47
<
jhass >
>> def foo(x); p(x); end; foo(:wrap => true)
05:47
<
CeBot >
jhass: Syntax error in eval:3: expecting token ')', not '=>'
05:47
<
jhass >
every argument can be passed as keyword though
05:47
<
epitron >
>> IO.popen
05:47
<
CeBot >
epitron: Error in line 3: undefined method 'popen' for IO:Class
05:47
<
epitron >
a keyword?
05:47
<
jhass >
>> def foo(x); p(x); end; foo(x: true)
05:47
<
CeBot >
jhass: Error in line 3: wrong number of arguments for 'foo' (0 for 1)
05:47
<
jhass >
oh, at least I though so
05:47
shama has quit [Quit: (╯°□°)╯︵ɐɯɐɥs]
05:48
<
epitron >
>> def foo(x: false); p x; end; foo(x: true)
05:48
<
CeBot >
epitron: Syntax error in eval:3: expecting token 'CONST', not 'false'
05:48
<
jhass >
>> def foo(x=nil); p(x); end; foo(x: true)
05:48
<
CeBot >
jhass: true
05:48
<
epitron >
>> def foo(*args); p args; end; foo(1,2,3,4,5)
05:48
<
CeBot >
epitron: {1, 2, 3, 4, 5}
05:48
<
CeBot >
epitron: Syntax error in eval:3: for empty hashes use '{} of KeyType => ValueType'
05:49
<
epitron >
>> {"a": 5}
05:49
<
CeBot >
epitron: {"a" => 5}
05:49
<
jhass >
>> Tuple.new
05:49
<
epitron >
>> h = {"a": 5}; h[5] = "lolz"
05:49
<
CeBot >
jhass: {1, 2, 3}
05:49
<
CeBot >
epitron: Error in line 3: no overload matches 'Hash(String, Int32)#[]=' with types Int32, String
05:50
<
jhass >
you can propose to support the implicit hash, but I think it's not very useful in crystal
05:50
<
epitron >
can values be different types?
05:50
<
epitron >
that was pretty useful
05:50
<
jhass >
yes, with a union
05:51
<
epitron >
>> {"a": 5, "b": [6,7,8]}
05:51
<
CeBot >
epitron: {"a" => 5, "b" => [6, 7, 8]}
05:51
<
epitron >
is that a union?
05:51
<
jhass >
>> {"a": 5, "b": [6,7,8]}.class
05:51
<
CeBot >
jhass: Hash(String, (Int32 | Array(Int32)))
05:51
<
epitron >
interesting
05:51
<
epitron >
>> {} of String => (Int32 | Array(Int32))
05:51
<
CeBot >
epitron: {}
05:52
<
epitron >
>> {} of String => (Int32 | Array(Int32) | Int(Array32))
05:52
<
CeBot >
epitron: Error in line 3: undefined constant Array32 (did you mean 'Array'?)
05:52
<
jhass >
you can then call all methods that are common to those types
05:52
<
epitron >
so it's a method dispatch thing
05:52
<
jhass >
if you want to call methods that only one instance has, you have to do something like v = h[key]; v.x if v.is_a? X
05:52
<
epitron >
it doesn't support
__END__
05:53
<
jhass >
another issue to open at github then ;)
05:53
<
jhass >
I'm sure it's something that would be accepted
05:54
<
jhass >
although it's harder to implement than in an interpreted language
05:54
<
epitron >
include? changed to includes? with no alias
05:54
<
jhass >
same for starts_with?, ends_with?
05:54
<
epitron >
Regexp changed to Regex
05:54
<
jhass >
they think it's more correct
05:54
<
epitron >
porting ruby code is going to be annoying
05:54
<
jhass >
Regex is probably an accident
05:54
<
epitron >
why not just put compatability methods?
05:55
<
jhass >
it's a different language really
05:55
<
jhass >
it would just give a false impression
05:55
<
jhass >
the syntax is inspired by Ruby, but it's not Ruby
05:55
<
epitron >
Regexp::IGNORECASE changed to Regex::IGNORE_CASE
05:55
<
jhass >
File.read_lines
05:55
<
epitron >
i know, but like -- it saves memory space if i don't have to remember two almost BUT NOT QUITE identical syntaxes :)
05:56
<
epitron >
that's maddening
05:56
<
epitron >
it's like trying to use a mac keyboard when coming from a PC
05:56
<
epitron >
everything is JUST SLIGHTLY off
05:56
<
epitron >
not enough to stop you from working, but enough to keep you out of flow
05:56
<
jhass >
anyway, as said, open class model
05:56
<
epitron >
i mean, it's just naming
05:57
<
jhass >
you can just make your compatibility layer as a library if you need it that badly ;)
05:57
<
jhass >
Ruby stdlib naming has quite a few inconsistencies though
05:57
<
epitron >
yeah, i agree
05:57
<
epitron >
but it doesn't hurt to have an EXTRA method for the ruby way
05:57
<
jhass >
cargo culting them to a new language is not really a good idea either
05:58
<
epitron >
like alias include?, includes?
05:58
<
epitron >
i understand that you don't want people to think it's ruby
05:58
<
epitron >
but it helps if i don't have to keep looking things up to fix a one char difference :)
05:59
<
jhass >
anyway, I'm not the language designer, asterite and waj are, if you feel strong about any of these points you should open issues at github, we love to discuss ;)
06:00
<
epitron >
in /home/epi/src/crystal/f.cr:152: wrong number of block arguments (2 for 0)
06:00
<
epitron >
breadth_first_scan(root) do |dirname, filename|
06:01
<
epitron >
all my yields supply 2 args
06:02
<
jhass >
ah yes, def a(&block); b(&block); end; doesn't interfere block args properly yet
06:02
<
jhass >
you need to give crystal a hint there:
06:02
<
jhass >
def breadth_first_scan(&block : (String, String) ->)
06:03
<
epitron >
block_spec.cr has some examples
06:04
<
epitron >
&block : Int32 -> Int32
06:04
<
epitron >
does that mean args -> return type?
06:05
<
jhass >
if you leave either side of, crystal tries to interfere it
06:06
<
epitron >
"U" is a magic type?
06:07
<
jhass >
if the type is unknown (and i think it needs to be a single uppercase letter), it's a template type
06:07
<
jhass >
like generics in java
06:07
<
epitron >
>> s = "string"; s["i"]
06:07
<
CeBot >
epitron: Error in line 3: no overload matches 'String#[]' with types String
06:07
<
jhass >
in this case, this makes it so that the return side doesn't become a union of all the possible return types
06:08
<
jhass >
but instead a method for each possible return type is instantiated
06:08
<
epitron >
so it means U(nknown)?
06:08
<
jhass >
it's just a letter
06:08
<
jhass >
could be T or whatever
06:09
<
epitron >
names should mean things :(
06:09
<
jhass >
you capture something there
06:09
<
jhass >
you choose the name
06:09
<
jhass >
R would be better there I guess, like Return type
06:09
<
epitron >
it could be a keyword
06:09
<
epitron >
Type -> return
06:10
<
epitron >
well, something not already used :)
06:10
bcardiff has quit [Quit: Leaving.]
06:10
<
jhass >
it's way more generic than that
06:10
<
jhass >
class Foo(T); def foo(x : T); end
06:10
<
jhass >
it really is like a java generic
06:11
<
jhass >
(and yes, java can have generics per method too)
06:11
<
epitron >
i'll have to read up on those
06:11
<
epitron >
i haven't used java in 15 years
06:11
<
jhass >
I'd imagine C++ has something for that too
06:11
<
epitron >
i haven't used C++ in 13 years
06:12
<
epitron >
actually, i used it a bit in december :)
06:12
<
epitron >
baka-mplayer is a nice video player
06:12
<
epitron >
i hacked in a couple features
06:12
<
jhass >
>> def foo(&block : -> R); block.class; end; {foo { 1 }, foo { "hi" }}
06:12
<
CeBot >
jhass: {( -> Int32), ( -> String)}
06:12
<
jhass >
>> def foo(&block); block.class; end; {foo { 1 }, foo { "hi" }}
06:12
<
CeBot >
jhass: {( -> Void), ( -> Void)}
06:12
<
epitron >
interesting
06:12
<
jhass >
>> def foo(&block : -> String|Int); block.class; end; {foo { 1 }, foo { "hi" }}
06:12
<
CeBot >
jhass: {( -> Int32), ( -> String)}
06:13
<
jhass >
oh, I expected a union there :D
06:13
<
epitron >
compiler got smarter
06:14
<
jhass >
>> def foo(&block : -> R); R.class; end; {foo { 1 }, foo { "hi" }}
06:14
<
CeBot >
jhass: in line 3: undefined constant R
06:15
<
jhass >
>> def foo(x : R); R.class; end; {foo(1), foo("hi")}
06:15
<
CeBot >
jhass: {Class, Class}
06:15
<
epitron >
"def []?" is interesting
06:15
<
jhass >
yeah, we take care to return less nils so you don't have to resolve the union with nil all the time
06:16
<
jhass >
so you have to explicitly request nil if you are not sure and don't want an exception
06:16
<
jhass >
>> def foo(x : R); R; end; {foo(1), foo("hi")}
06:16
<
CeBot >
jhass: {Int32, String}
06:16
<
jhass >
>> def foo(x); x.class; end; {foo(1), foo("hi")}
06:16
<
CeBot >
jhass: {Int32, String}
06:16
<
jhass >
mmh, it really got smarter :P
06:17
<
jhass >
>> def foo(x); [x].class ; end; {foo(1), foo("hi")}
06:17
<
CeBot >
jhass: {Array(Int32), Array(String)}
06:18
<
epitron >
oh wait! you DO have popen!
06:18
<
epitron >
there's bindings to the C library, but no ruby implementation
06:19
<
epitron >
s/ruby/crystal/
06:19
<
jhass >
epitron: well, Process.run can do it's everyday usecases already
06:19
<
jhass >
except for stderr
06:19
<
jhass >
but I plan to add that soon
06:19
<
epitron >
>> LibC.popen
06:19
<
CeBot >
epitron: Error in line 3: wrong number of arguments for 'LibC#popen' (0 for 2)
06:19
<
epitron >
Process.run, eh?
06:19
<
jhass >
after we got IO.select working
06:20
<
jhass >
>> Process.run("/bin/cat", "/etc/groups")
06:20
<
CeBot >
jhass: in /usr/lib/crystal/process/run.cr:9: undefined method 'each' for String
06:20
<
epitron >
i don't see Process.run
06:20
<
jhass >
>> Process.run("/bin/cat", {"/etc/groups"})
06:20
<
CeBot >
jhass: /bin/cat: /etc/groups: No such file or directory
06:20
<
jhass >
>> Process.run("/bin/cat", {"/etc/group"})
06:20
<
CeBot >
jhass: Process::Status(@pid=53, @exit=0, @output=nil)
06:20
<
jhass >
>> Process.run("/bin/cat", {"/etc/group"}, output: true).output
06:20
<
epitron >
oh, there it is
06:20
<
epitron >
process/run.cr
06:21
<
jhass >
>> io = StringIO.new; Process.run("/bin/cat", {"/etc/group"}, output: io); io.read
06:21
<
CeBot >
jhass: Error in line 3: wrong number of arguments for 'StringIO#read' (0 for 1, 2)
06:21
<
jhass >
>> io = StringIO.new; Process.run("/bin/cat", {"/etc/group"}, output: io); io.read(8)
06:21
<
epitron >
>> LibC.popen("ls", "r").read
06:21
<
CeBot >
epitron: Error in line 3: undefined method 'read' for LibC::File
06:21
<
epitron >
how do you read a file?
06:22
<
epitron >
>> LibC.popen("ls", "r")
06:22
<
CeBot >
epitron: Sorry, I can't let you do that.
06:22
<
jhass >
File.open is there too I think
06:22
<
epitron >
i mean, popen returns a LibC::File
06:22
<
epitron >
>> LibC.fread( LibC.popen("ls", "r") )
06:22
<
CeBot >
epitron: Error in line 3: wrong number of arguments for 'LibC#fread' (1 for 4)
06:23
<
jhass >
I think you shouldn't use bindings in application code though
06:23
<
epitron >
yeah, i'll wrap it :)
06:23
<
jhass >
wrap it, if you think it's interesting for stdlib, pull request
06:23
<
jhass >
in doubt, pull request
06:24
<
CeBot >
epitron: IO
06:24
<
epitron >
so, ruby puts popen on IO
06:24
<
jhass >
what's wrong with Process.run though?
06:25
<
epitron >
CFileIO is where the rest of the stuff is
06:25
<
epitron >
i like IO.popen beacuse it gives you a file handle
06:25
<
epitron >
so you can read a line at a time
06:25
<
epitron >
streaming output
06:25
<
jhass >
did you see my StringIO example?
06:25
<
epitron >
and it lets you write to its stdin
06:26
<
epitron >
IO.popen("less", "w") { |less| 100.times { less.puts "yay" } }
06:26
<
jhass >
>> io = StringIO.new; Process.run("/bin/cat, output: io, input: "hi"); io.read(8)
06:26
<
CeBot >
jhass: Syntax error in eval:3: expecting token ')', not 'hi'
06:26
<
epitron >
missing a "
06:26
<
jhass >
>> io = StringIO.new; Process.run("/bin/cat", output: io, input: "hi"); io.read(8;5B
06:26
<
CeBot >
jhass: Syntax error in eval:3: expecting token ')', not ';'
06:26
<
jhass >
>> io = StringIO.new; Process.run("/bin/cat", output: io, input: "hi"); io.gets
06:27
bcardiff has joined #crystal-lang
06:27
<
epitron >
IO.popen is pretty nice imo
06:27
<
jhass >
in theory Process.run should cover these usecases
06:28
<
epitron >
i don't wanna mess with StringIOs :(
06:28
<
jhass >
>> r, w = IO.pipe; Process.run("/bin/cat", output: w, input: "hi"); r.read
06:28
<
CeBot >
jhass: Error in line 3: wrong number of arguments for 'FileDescriptorIO#read' (0 for 1, 2)
06:28
<
jhass >
>> r, w = IO.pipe; Process.run("/bin/cat", output: w, input: "hi"); r.gets
06:28
<
CeBot >
jhass: Sorry, that took too long.
06:28
<
epitron >
IO.popen("ls") { |output| puts output.read }
06:28
<
epitron >
so simple
06:29
<
epitron >
IO.popen("cat", "w") { |input| input.puts "yay" }
06:29
<
jhass >
>> r, w = IO.pipe; Process.run("/bin/cat", output: w, input: "hi\n"); r.gets
06:29
<
CeBot >
jhass: Sorry, that took too long.
06:30
<
jhass >
>> r, w = IO.pipe; Process.run("/bin/cat", output: w, input: "hi\n"); r.read(1)
06:30
<
CeBot >
jhass: Sorry, that took too long.
06:31
<
jhass >
it actually, works
06:31
<
jhass >
I block something in the sandbox
06:32
<
jhass >
anyway, nothing against a nice abstraction upon it though ;)
06:32
<
jhass >
contributing to and shaping stdlib is part of the fun of being early in this game ;)
06:33
<
epitron >
in /home/epi/src/crystal/f.cr:56: undefined method 'not'
06:33
<
jhass >
like I added max_of and variants yesterday
06:34
<
epitron >
max_of, eh?
06:35
<
jhass >
replaces .map(&.x).max and .max_by(&.x).x
06:36
<
epitron >
i dunno, the name doesn't sound like it maps
06:36
<
epitron >
it sounds like it just finds the max value
06:36
<
epitron >
"max element of this set"
06:36
<
epitron >
"max_where" maybe makes more sense
06:36
<
epitron >
"max element where the element is the square of itself"
06:37
<
jhass >
well, you call it on the set
06:37
<
epitron >
yeah, but like...
06:37
<
epitron >
i think "_of" isn't the right name
06:37
<
jhass >
probably, I'm not a native speaker after all
06:38
<
epitron >
oh really?
06:38
<
epitron >
where do you hail from? :)
06:38
<
jhass >
_where sounds like _by to me though
06:38
<
epitron >
ahh, cool
06:38
<
epitron >
_suchthat? :)
06:39
<
epitron >
how about max_map
06:39
<
jhass >
it's not really a map
06:39
<
jhass >
more a _find
06:39
<
epitron >
assert { [-1, -2, -3].max_of { |x| -x }.should eq(3) }
06:39
<
jhass >
that's just max
06:39
<
epitron >
it transforms the -3 to 3
06:39
<
jhass >
it returns the value of the block
06:40
<
epitron >
so, with_max { |v| }
06:40
<
epitron >
but the max would be -1 in that case
06:40
<
jhass >
it's .map {|x| -x }.max
06:40
<
jhass >
without the extra array alloc
06:40
<
epitron >
maxmap :)
06:40
<
epitron >
or map_max?
06:41
<
jhass >
I don't think that's clearer tbh
06:41
<
epitron >
max_of really doesn't sound like what it's doing
06:41
<
epitron >
max_of_mapped_values
06:41
<
epitron >
that's what you mean
06:42
<
jhass >
maximum of these values
06:42
<
epitron >
these values.. which are being transformed (mapped) by the block
06:42
<
epitron >
you're just hoping the user guesses that the block is mapping them
06:43
<
jhass >
dunno, I was hoping for the shortcut syntax, really
06:43
<
epitron >
"max" and "max_of" really sounds like the same thing to me
06:43
<
epitron >
it sounds like the real value is the memory savings
06:43
<
epitron >
saving 3 characters isn't really a big deal
06:44
<
jhass >
well, the other case is .max_by(&.x).x
06:44
<
jhass >
where it DRYs up your code and avoids potentially expensive .x a second time
06:44
<
epitron >
wait, what does .x do?
06:44
<
jhass >
whatever, it's a method call
06:45
<
jhass >
except way more powerful
06:45
<
epitron >
yeah, i get that
06:45
<
epitron >
but you have another .x
06:45
<
epitron >
what's the second one do?
06:45
<
jhass >
max_by returns the item that the block returned the highest value for
06:46
<
jhass >
not the highest value itself
06:46
<
jhass >
so if you want to get to the highest value itself in ruby
06:46
<
jhass >
you either have to extra array alloc with .map(&:x).max
06:46
<
jhass >
which sucks with many elements
06:47
<
jhass >
or repeat the computation of .x with .max_by(&:x).x
06:47
<
jhass >
which sucks if .x is expensive
06:47
<
epitron >
i don't understand what .x means at the end!
06:47
<
epitron >
what are you mapping? an array of integers?
06:47
<
jhass >
and sucks if :x is actually .a_really_long_method_name
06:47
<
epitron >
so "x" is some random method?
06:47
<
jhass >
whatever, it's just the abstract example
06:48
<
epitron >
so, for example, strings.max_by(&.size).size?
06:48
<
epitron >
strings.max_map(&.size) sounds good to me :D
06:48
<
jhass >
highscore = users.max_of(&.score)
06:49
<
epitron >
actually, users.max(&.score)
06:49
<
epitron >
that sounds pretty good to me
06:49
<
jhass >
that returns the user though
06:49
<
jhass >
not their score
06:50
<
epitron >
i think if you pass a block, it should return what max_of does
06:50
<
epitron >
no block returns the user
06:50
<
epitron >
and max_by(&.score) would return the user
06:50
<
jhass >
ArgumentError: wrong number of arguments (1 for 0)
06:50
<
epitron >
users.max(&.score) sounds like you want the score, not the user
06:50
<
jhass >
["a", "aa", "aaa"].max(&:size)
06:51
<
epitron >
users.max => "gimme the max user"
06:51
<
epitron >
users.max(&.score) => "gimme the max score
06:51
<
jhass >
well, easy change
06:51
<
jhass >
another pull request ;)
06:51
<
epitron >
users.max_by(&.score) => "gimme the user with the max score"
06:51
<
jhass >
another better place to discuss )
06:52
<
epitron >
i find it frustrating to convince people over pull requests
06:52
<
epitron >
look how much back and forth it took me to convince you :)
06:52
<
epitron >
it would be like 50 messages on github
06:52
<
jhass >
I don't think that's a bad thing
06:52
<
jhass >
gives you discussion to refer to in the future
06:53
<
epitron >
yeah, that is nice
06:53
<
jhass >
we do that extensively on diaspora
06:53
<
jhass >
works quite well
06:53
<
epitron >
the problem is that if it takes a long time between replies, you can forget what you were talking about :)
06:53
<
epitron >
diaspora is still alive? :O
06:53
<
epitron >
i do like technical discussions on github
06:54
<
epitron >
coffeescript was really cool
06:54
<
jhass >
+5k users in the last days ;)
06:54
<
epitron >
they designed the language in issues
06:54
<
epitron >
did you guys drop a new release?
06:54
<
epitron >
what did FB do now
06:54
<
jhass >
updated the ToS
06:55
<
epitron >
dah, no Interrupt exception
06:55
<
CeBot >
Reloaded plugin configuration.
06:55
<
CeBot >
diaspora* approximately had 27810 active users in the last 30 days and 80862 active users in the last 180 days.
06:55
<
epitron >
^CProgram terminated abnormally with error code: 2
06:56
<
epitron >
how do i rescue that? :)
06:56
<
jhass >
Signal.trap
06:56
<
jhass >
yeah, it's no exception yet
06:56
<
epitron >
i'll just let the program blow up
06:56
<
jhass >
it's not easy to do, there's no runtime that could inject stuff
06:57
<
epitron >
i got it to build!
06:57
<
epitron >
it loads so FAST!
06:58
<
epitron >
i just get an "index out of bounds" when i acually try to use it
06:58
<
epitron >
--help works tho!
07:00
<
epitron >
>> "hello"[-1]
07:00
<
CeBot >
epitron: Failed to run your code, sorry!
07:00
<
epitron >
>> s = "hello"; s[-1]
07:00
<
CeBot >
epitron: Failed to run your code, sorry!
07:00
<
epitron >
>> s = "hello"; s.chars
07:00
<
CeBot >
epitron: Failed to run your code, sorry!
07:00
<
epitron >
>> s = "hello"
07:00
<
CeBot >
epitron: Failed to run your code, sorry!
07:00
<
jhass >
I borked the whitelist, sorry
07:01
<
jhass >
>> "hello"[-1]
07:02
<
epitron >
hashes don't return nil if the key doesn't exist
07:02
<
epitron >
do i use "fetch"?
07:03
<
epitron >
>> h = {"a": 1}; h.fetch("b")
07:03
<
CeBot >
epitron: #{e.class}: Missing hash value: b
07:03
<
epitron >
>> h = {"a": 1}; h.fetch("b", nil)
07:03
<
CeBot >
epitron: nil
07:03
<
epitron >
>> h = {"a": 1}; h.fetch("b", "whee")
07:03
<
CeBot >
epitron: "whee"
07:03
<
epitron >
>> h = {"a": 1}; h.includes?("b")
07:03
<
CeBot >
epitron: Error in line 3: undefined method 'includes?' for Hash(String, Int32)
07:03
<
epitron >
>> h = {"a": 1}; h.include?("b")
07:03
<
CeBot >
epitron: Error in line 3: undefined method 'include?' for Hash(String, Int32)
07:03
<
jhass >
>> {a: "x"}[:b]?
07:04
<
jhass >
#[] raises, #[]? returns nil
07:04
<
epitron >
so, returning nil is a performance hit?
07:05
<
jhass >
ideally for all interfaces that define #[], I know it does for Array, Hash & MatchData currently
07:05
<
jhass >
no, it's just inconvenient if you're sure that the index is there
07:05
<
jhass >
since you get a union with nil
07:05
<
epitron >
but it's nice to be able to do: "if x = hash[key]"
07:05
<
jhass >
and that has very few methods left
07:05
<
epitron >
check and assign in once!
07:05
<
jhass >
you can do that with #[]? just fine
07:05
<
epitron >
i have to type hash[key] twice though
07:06
<
epitron >
if hash[key]?
07:06
<
epitron >
x = hash[key]
07:06
<
jhass >
>> h = {a: "b"}; x if x = h[:a]?
07:06
<
CeBot >
jhass: Error in line 3: undefined local variable or method 'x' (did you mean 'x'?)
07:06
<
jhass >
>> h = {a: "b"}; if x = h[:a]?; x; end
07:06
<
jhass >
>> h = {a: "b"}; if x = h[:b]?; x; end
07:07
<
jhass >
the modifer-if issue there is probably a bug
07:07
<
epitron >
i was expecting "?" to return bools
07:07
<
epitron >
why not just have [] return nil?
07:07
<
jhass >
it's more often "includes nil" in crystal
07:07
<
jhass >
in fact Foo? is a shortcut to Foo|Nil
07:08
<
epitron >
that's a big semantic change from ruby
07:08
<
jhass >
>> def foo(x : String); x; end; foo(nil)
07:08
<
CeBot >
jhass: Error in line 3: no overload matches 'foo' with types Nil
07:08
<
jhass >
>> def foo(x : String?); x; end; foo(nil)
07:08
<
jhass >
>> def foo(x : String|nil); x; end; foo(nil)
07:08
<
CeBot >
jhass: Syntax error in eval:3: expecting token 'CONST', not 'nil'
07:08
<
jhass >
>> def foo(x : String|Nil); x; end; foo(nil)
07:08
<
jhass >
last (working) two are the same thing
07:08
<
epitron >
i got an idea.. how about, "hash[key]" returns Foo|Nil, "hash[key]?" returns Bool, and "hash[key]?!" raises exceptions :D
07:09
<
jhass >
turns out you actually know whether your index should exist or not
07:09
<
jhass >
in most cases
07:09
<
jhass >
so I think having the "normal" call the most convenient one is good
07:11
<
jhass >
also I don't get why we would need an explicit variant for Bool
07:11
<
epitron >
well, because you got rid of "includes?"
07:11
<
jhass >
Crystal has the same semantics for truthiness/falsiness as Ruby
07:11
<
epitron >
i actually really like the "hash[key]?" or "array[index]?" instead of "includes?"
07:12
<
epitron >
that's a great idea :)
07:12
<
epitron >
includes is CRAP
07:12
<
epitron >
sorry, i gotta bug report all these ideas
07:14
<
epitron >
man, i'm going to make a repl
07:14
<
epitron >
this is too annoying
07:21
<
jhass >
while true; do echo -n "> "; read input; echo "p begin; $input; end" | crystal eval; done
07:22
<
epitron >
mine has history :D
07:22
<
epitron >
and it puts the result AFTER all the putses
07:22
<
epitron >
oh wait, so does yours
07:22
<
epitron >
mine has a => though!
07:23
<
jhass >
well, that's just a echo -n "=>" away
07:23
<
jhass >
yours has Ctrl+D I guess
07:23
<
epitron >
you gotta echo the => after the eval, but before the answer though
07:24
<
epitron >
you'd need a temp variable
07:25
<
jhass >
why can't I echo it before the eval?
07:46
<
epitron >
OMG it has colorize built in! :D
07:46
<
epitron >
this is really nice
07:46
<
epitron >
i like ruby C
07:48
<
epitron >
i really like how i can hack the STDLIB and it's all available instantly
07:48
<
epitron >
i thought i'd have to recompile crystal originally
07:48
<
epitron >
LLVM is awesome
07:54
<
jhass >
unless you turn on the optimization phase :P
07:54
<
jhass >
(bin/crystal build --release)
08:11
bcardiff has quit [Quit: Leaving.]
08:27
<
epitron >
woohoo, it works!
08:27
<
epitron >
there's still some gross stuff in here, but it finally works
08:28
<
epitron >
i couldn't get colorize working though
08:29
<
epitron >
jhass: thanks for all your help
08:29
<
epitron >
this is an exciting language
08:29
<
epitron >
it really works well
08:54
r20 has quit [Ping timeout: 272 seconds]
08:58
gr33n7007h has quit [Ping timeout: 265 seconds]
11:35
asterite has joined #crystal-lang
11:35
<
asterite >
>> Time.now
11:35
<
CeBot >
asterite: 2015-01-31 11:35:57
11:39
asterite has quit [Client Quit]
11:47
asterite has joined #crystal-lang
11:58
asterite has quit [Quit: Page closed]
12:17
travis-ci has joined #crystal-lang
12:17
<
travis-ci >
manastech/crystal#1873 (master - 409b843 : Ary Borenszweig): The build passed.
12:17
travis-ci has left #crystal-lang [#crystal-lang]
14:22
zamith has joined #crystal-lang
14:38
travis-ci has joined #crystal-lang
14:38
<
travis-ci >
manastech/crystal#1875 (master - 81f191e : Ary Borenszweig): The build passed.
14:38
travis-ci has left #crystal-lang [#crystal-lang]
14:49
bcardiff has joined #crystal-lang
15:04
leafybasil has joined #crystal-lang
15:13
travis-ci has joined #crystal-lang
15:13
<
travis-ci >
manastech/crystal#1877 (master - 97c4dff : Ary Borenszweig): The build passed.
15:13
travis-ci has left #crystal-lang [#crystal-lang]
15:20
travis-ci has joined #crystal-lang
15:20
<
travis-ci >
manastech/crystal#1878 (master - d3b1c67 : Ary Borenszweig): The build passed.
15:20
travis-ci has left #crystal-lang [#crystal-lang]
15:22
travis-ci has joined #crystal-lang
15:22
<
travis-ci >
manastech/crystal#1879 (master - d8149f9 : Ary Borenszweig): The build passed.
15:22
travis-ci has left #crystal-lang [#crystal-lang]
15:26
bcardiff has left #crystal-lang [#crystal-lang]
15:48
zamith has quit [Quit: Be back later ...]
16:25
r20 has joined #crystal-lang
16:46
leafybasil has quit [Remote host closed the connection]
17:01
<
jhass >
shouldn't be much longer, maybe another 50 lines to bidn the C functions
17:01
<
jhass >
though, I'd rather try to do it for wayland ;P
17:10
travis-ci has joined #crystal-lang
17:10
<
travis-ci >
manastech/crystal#1880 (master - 8bdc6cd : Ary Borenszweig): The build passed.
17:10
travis-ci has left #crystal-lang [#crystal-lang]
17:14
travis-ci has joined #crystal-lang
17:14
<
travis-ci >
manastech/crystal#1881 (master - bfb7b6d : Ary Borenszweig): The build was broken.
17:14
travis-ci has left #crystal-lang [#crystal-lang]
17:19
asterite has joined #crystal-lang
17:25
<
jhass >
asterite: you should add that to package control ;)
17:26
<
asterite >
how to do that?
17:27
<
asterite >
Cool, thanks. I'll submit it later
17:34
asterite has quit [Ping timeout: 246 seconds]
17:36
leafybasil has joined #crystal-lang
17:48
drizz_ has joined #crystal-lang
18:12
leafybasil has quit [Remote host closed the connection]
18:22
gr33n7007h has joined #crystal-lang
19:25
drizz has quit [Quit: Lost terminal]
19:25
drizz_ is now known as drizz
20:13
travis-ci has joined #crystal-lang
20:13
<
travis-ci >
manastech/crystal#1883 (master - bc7bca2 : Ary Borenszweig): The build is still failing.
20:13
travis-ci has left #crystal-lang [#crystal-lang]
20:21
bcardiff has joined #crystal-lang
20:37
ryanf has joined #crystal-lang
20:58
havenwood has joined #crystal-lang
20:59
zamith has joined #crystal-lang
23:34
havenwood has quit [Remote host closed the connection]
23:38
leafybasil has joined #crystal-lang
23:39
kgadek has quit [Ping timeout: 264 seconds]
23:40
bcardiff has quit [Quit: Leaving.]
23:42
Prawnzy has quit [Ping timeout: 264 seconds]
23:45
irclogger_______ has joined #crystal-lang
23:46
irclogger______ has quit [Ping timeout: 264 seconds]
23:46
Prawnzy has joined #crystal-lang
23:48
kgadek has joined #crystal-lang
23:48
<
epitron >
hey, i wanna write some C bindings
23:49
<
epitron >
how do i pass a pointer to an array of pointers to strings?
23:49
<
epitron >
Pointer(Pointer(String))?
23:50
<
jhass >
what's the c function signature?
23:50
<
jhass >
you might want that Slice stuff, I didn't fully checked it yet
23:51
<
epitron >
it's just an exec that takes multiple args
23:51
<
epitron >
slice, eh?
23:51
<
jhass >
Slice is a Pointer with an associated length
23:51
<
jhass >
good for C array stuff I gather
23:51
<
jhass >
or maybe not
23:52
<
jhass >
as said I didn't fully check it out yet
23:52
<
epitron >
>> ["hello", "there"].map(&.cstr).buffer
23:52
<
CeBot >
epitron: Pointer(Pointer(UInt8))@98F5FE0
23:52
<
epitron >
i think that's what i want?
23:52
<
jhass >
I guess so, just try it out :)
23:52
<
jhass >
>> ["hello", "there"].map(&.cstr).to_unsafe
23:52
<
CeBot >
jhass: Pointer(Pointer(UInt8))@9698FE0
23:53
<
jhass >
to_unsafe is called when you just pass the object and it defines it
23:53
<
jhass >
like to_s when you use an object in "#{}"
23:53
<
jhass >
>> {"hello", "there"}.to_unsafe
23:53
<
CeBot >
jhass: Error in line 3: undefined method 'to_unsafe' for {String, String}
23:54
<
jhass >
>> ["hello", "there"].to_unsafe
23:54
<
CeBot >
jhass: Pointer(String)@96C0FF0
23:54
<
jhass >
so I'd try exec a, b.map(&.cstr)
23:56
<
epitron >
>> LibC.system(["ls", "-l"].map(&.cstr).buffer)
23:56
<
CeBot >
epitron: Error in line 3: argument 'str' of 'LibC#system' must be Pointer(UInt8), not Pointer(Pointer(UInt8))
23:56
<
epitron >
oh, i had to change system to UInt8**
23:56
<
epitron >
anyhow, it says "sh: t]@: command not found"
23:56
<
epitron >
apparently it's running a shell too
23:57
<
jhass >
watch trying?
23:57
<
jhass >
>> system("ls")
23:57
<
CeBot >
jhass: true
23:57
<
epitron >
yeah, but system can only take one arg
23:57
<
epitron >
i want system to take multiple args
23:57
<
epitron >
so i don't have to shell escape stuff
23:57
<
epitron >
or run a shell at all
23:57
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}).output
23:58
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}).output.gsub("\n", ",")
23:58
<
CeBot >
jhass: Error in line 3: undefined method 'gsub' for Nil
23:58
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}).output.not_nil!.gsub("\n", ",")
23:58
<
CeBot >
jhass: Error in line 3: no overload matches 'String#gsub' with types String, String
23:58
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}).output.not_nil!.gsub('\n', ,")
23:58
<
CeBot >
jhass: Syntax error in eval:3: unterminated call
23:58
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}).output.not_nil!.gsub('\n', ',')
23:58
<
jhass >
Process.run is the way IMO
23:59
<
epitron >
but that captures the output
23:59
<
epitron >
system just runs the command
23:59
<
epitron >
and the command outputs to your terminal
23:59
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}, output: false).output.not_nil!.gsub('\n', ',')
23:59
<
CeBot >
jhass: #{e.class}: Nil assertion failed
23:59
<
jhass >
>> Process.run("/bin/ls", {"-a", "/"}, output: false).success?
23:59
<
CeBot >
jhass: true