Show enters and exits. Hide enters and exits.
| 00:00:01 | boyscout | Cleanup GC specs, remove useless tests. - dafae6c - Evan Phoenix |
| 00:00:01 | boyscout | Stub out GC methods, pass all specs. - abee1a2 - Evan Phoenix |
| 00:00:01 | boyscout | Use mock_numeric rather than NumericSub - 3b13360 - Evan Phoenix |
| 00:00:01 | boyscout | Clarify edge case in Numeric#coerce specs - e688abf - Evan Phoenix |
| 00:00:01 | boyscout | Fix Numeric#ceil and Numeric#floor - 4f211f3 - Evan Phoenix |
| 00:00:02 | boyscout | Add Numeric#coerce class checking - c2fef06 - Evan Phoenix |
| 00:00:04 | boyscout | Get the numeric tower more compatible with MRI. - e315ca0 - Evan Phoenix |
| 00:04:04 | boyscout | CI: rubinius: e315ca0 successful: 3024 files, 11768 examples, 36003 expectations, 0 failures, 0 errors |
| 00:53:39 | rue | FFS |
| 01:27:06 | boyscout | Fix UnboundMethod#name to return a String, not a Symbol - a01c37d - Evan Phoenix |
| 01:27:06 | boyscout | Fix some Enumerable edge cases - e871a59 - Evan Phoenix |
| 01:27:06 | boyscout | Clean up Comparable - 5dcfdb1 - Evan Phoenix |
| 01:41:36 | boyscout | CI: rubinius: 5dcfdb1 successful: 3024 files, 11770 examples, 36007 expectations, 0 failures, 0 errors |
| 03:27:29 | boyscout | ENV.index: implementation - 9957f99 - Marc-Andre Lafortune |
| 03:31:28 | boyscout | CI: rubinius: 9957f99 successful: 3024 files, 11770 examples, 36007 expectations, 0 failures, 0 errors |
| 19:20:27 | kstephens | can anybody point me to documentation/examples on how to interface a write-barrier GC into rubininus? |
| 19:20:46 | evan | there is none of those things |
| 19:20:57 | evan | there is really just the code for the existing one |
| 19:21:04 | rue | Though the GC already uses a write barrier |
| 19:21:12 | kstephens | I have a real-time GC i've written that i'd like to try out. |
| 19:21:42 | kstephens | http://kurtstephens.com/pub/tredmill/current/doc/html/index.html |
| 19:22:51 | evan | well |
| 19:22:58 | evan | check in ObjectMemory |
| 19:23:00 | kstephens | it requires no separate GC thread, and is guaranteed to have bounded time during allocation. |
| 19:23:04 | evan | ObjectMemory::write_barirer |
| 19:23:23 | evan | you'd put a write barrier in there. |
| 19:24:03 | kstephens | does that generate LLVM code? or is it just called from LLVM compiled code? |
| 19:24:17 | evan | neither. |
| 19:24:23 | evan | well, LLVM calls that if it needs to. |
| 19:24:34 | evan | but thats pretty rare. |
| 19:24:34 | kstephens | how does LLVM decide? |
| 19:24:53 | evan | there isn't a lot of JIT generated code that directly manipulates references |
| 19:25:08 | kstephens | so it doesn't hit the write barrier before all object mutations? |
| 19:25:11 | evan | because CallFrame accessible references are always checked. |
| 19:25:20 | evan | so we don't run the write barrier for them. |
| 19:25:46 | kstephens | CallFrame is essentially the stack? |
| 19:26:20 | evan | yeah |
| 19:26:54 | kstephens | my GC may not require stack or global root write-barrier, if you configure it to make the root mark phase to be atomic. |
| 19:27:25 | evan | i thought treadmill required a read barrier |
| 19:27:30 | evan | to keep the object color correct. |
| 19:27:31 | kstephens | so what I'm looking for is a hook, where any mutations to objects allocated from the GC, will hit the write barrier first. |
| 19:27:47 | kstephens | my implementation uses a write barrier. |
| 19:27:48 | evan | oh |
| 19:27:49 | evan | first? |
| 19:27:55 | evan | it's always run after. |
| 19:27:56 | evan | atm. |
| 19:28:01 | kstephens | sorry, i meant "after" |
| 19:28:18 | evan | huh? |
| 19:28:22 | evan | say what you mean again. |
| 19:28:23 | kstephens | maybe this is more of an LLVM question. |
| 19:28:50 | kstephens | so what I'm looking for is a hook, where any mutations to objects allocated from the GC, will hit the write barrier after the mutation. |
| 19:29:23 | kstephens | but I must be able to guarantee that no allocations will occur between the mutation and calling the write barrier. |
| 19:29:42 | evan | ok, thats true. |
| 19:30:54 | kstephens | if stack frames are not allocated through the GC, i dont need a write barrier for those mutations. |
| 19:31:41 | kstephens | Does LLVM ever allocate objects on the stack? |
| 19:31:54 | evan | of course not. |
| 19:32:09 | evan | you can never do that in a GC. |
| 19:32:26 | evan | it allocates some data structures on the C stack, like the CallFrame |
| 19:32:40 | evan | but GC objects are only ever allocated by the GC. |
| 19:32:41 | kstephens | well, some system do use alloca() as a hemispace pointer: see chicken scheme. |
| 19:32:54 | evan | fuck no. |
| 19:33:01 | evan | that sounds like a lot of pain. |
| 19:33:28 | kstephens | well, not really. makes continuations a piece of cake. |
| 19:33:49 | evan | well |
| 19:33:51 | kstephens | in fact ordinary C code cant tell the difference. |
| 19:33:58 | evan | that sounsd like something else |
| 19:33:59 | kstephens | ... that is linked in. |
| 19:33:59 | evan | anyway. |
| 19:34:18 | evan | what do you want to know |
| 19:34:28 | evan | putting code in ObjectMemory::write_barrier is probably what you want |
| 19:34:57 | kstephens | and where would I interface calls to GC allocation? |
| 19:36:09 | evan | ObjectMemory::allocate_object |
| 19:36:18 | evan | is where all allocations go through |
| 19:36:34 | kstephens | great, thanks! |
| 19:36:43 | evan | well, ObjectMemory::allocate_object_mature too. |
| 19:37:04 | evan | you'll need to read BakerGC::collect though |
| 19:37:12 | kstephens | hmm, what's that for? |
| 19:37:16 | evan | for how to find the roots. |
| 19:38:05 | evan | BakerGC is semispace collector. |
| 19:38:10 | evan | used for the young generation. |
| 19:38:16 | kstephens | TM keeps a list of root spaces, but I should probably add a root scan callback. |
| 19:38:29 | evan | root spaces? |
| 19:38:50 | kstephens | regions of memory that contain roots. |
| 19:39:00 | kstephens | (or potential pointers) rather. |
| 19:39:09 | kstephens | TM is conservative. |
| 19:39:37 | evan | well |
| 19:39:52 | evan | you'll need to directly mark the roots rubinius gives you |
| 19:40:01 | evan | because the roots can spread out. |
| 19:40:02 | kstephens | I can add a callback for that. |
| 19:41:06 | kstephens | is the BakerGC compacting? |
| 19:41:12 | kstephens | ... just curious. |
| 19:41:26 | evan | oh yeah |
| 19:41:28 | evan | bigtime. |
| 19:41:30 | evan | so |
| 19:41:42 | evan | i guess you haven't work with rubinius before? |
| 19:41:47 | kstephens | nope |
| 19:42:06 | kstephens | at some point you weren't using LLVM, right? |
| 19:42:21 | evan | yeah, we introduce LLVM |
| 19:42:25 | evan | as the JIT |
| 19:42:29 | evan | but you can run rubinius without it. |
| 19:42:33 | evan | if you need. |
| 19:42:41 | kstephens | bytecode? |
| 19:42:53 | kstephens | or AST traversal? |
| 19:43:14 | kstephens | or native code gen? |
| 19:43:26 | evan | bytecode |
| 19:43:30 | kstephens | I guess if it was AST it wouldn't be faster than MRI 1.8.x |
| 19:43:31 | evan | how did you hear about rubinius? |
| 19:43:44 | evan | feels like this is the first day you're looking at it :) |
| 19:44:22 | kstephens | mostly watching how you guys in ruby-core list are trying to nail down how MRI really behaves :) |
| 19:45:01 | kstephens | language lawyers prevent confusion. |
| 19:45:47 | evan | ah, so this is the first time you're looking at rubinius, and thusly the insides. |
| 19:45:59 | kstephens | my interest in rubinius because MRI is kinda dead from the optimization and GC architecture angle. |
| 19:46:27 | kstephens | I've peeked around a bit and built it, but now its time to get my hands dirty. |
| 19:46:55 | evan | ok |
| 19:47:05 | evan | so, rubinius has always had an accurate GC |
| 19:47:16 | evan | so it's possible that there are things that depend on it |
| 19:47:24 | evan | that i can't think of right now |
| 19:47:58 | kstephens | conservative < accurate: as far as assumptions go. |
| 19:48:14 | evan | yeah |
| 19:48:25 | evan | you're more than welcome to play around, of course |
| 19:48:30 | kstephens | I have an write barrier that can take accurate pointers or not-so accurate pointers. |
| 19:48:31 | evan | but why would you want a conservative GC? |
| 19:48:38 | rue | I am glad my "subtle" hints at avoiding trying to fix MRI GC were heard :P |
| 19:48:54 | kstephens | The conservative part is not what I'm after, its the bounded allocation time. |
| 19:49:11 | kstephens | the real-time aspect of TM is where I think it applies here. |
| 19:49:25 | evan | well |
| 19:49:33 | evan | rubinius GC allocation time is bounded atm. |
| 19:49:35 | kstephens | The conservative part is mostly due to how I think it might work with non-GC aware libraries. |
| 19:49:45 | evan | it never GCs on allocation |
| 19:49:52 | evan | the allocator sets a hint |
| 19:50:00 | evan | that is seen later on and the GC is run |
| 19:51:02 | kstephens | does rubinous ever call malloc() directly (i.e. via C++ new operator, for example?) |
| 19:51:31 | evan | sure |
| 19:51:36 | kstephens | ok |
| 19:51:42 | kstephens | that's what I figured. |
| 19:51:43 | evan | why? |
| 19:52:01 | evan | all the VM internal data uses either malloc() or now |
| 19:52:01 | kstephens | I'll need to disable my malloc() hook. |
| 19:52:02 | evan | er. new. |
| 19:52:11 | evan | ah ok. |
| 19:53:46 | kstephens | i'm not sure my work will improve rubinius, but MRI is not a good research platform. |
| 19:54:04 | evan | surely |
| 19:54:15 | evan | i've tried to keep interfaces clean inside the VM |
| 19:54:21 | kstephens | i can tell |
| 19:54:31 | evan | so you should only have to touch a few points to change it |
| 19:54:57 | kstephens | frankly I like that its written in C++. |
| 19:55:06 | kstephens | C++ is the new assembler. |
| 19:55:17 | evan | :) i live that it is too |
| 19:55:24 | evan | it's made it easier to develop that doing it in C |
| 19:55:45 | kstephens | yup |
| 19:56:29 | kstephens | Thanks for answering my questions. |
| 19:56:34 | evan | no problem! |
| 19:56:36 | kstephens | Good info. |
| 19:56:40 | evan | i'm happy to help |
| 19:56:43 | evan | let me know what i can do |
| 19:57:10 | kstephens | tnx |
| 19:59:54 | kstephens | oh, one last question: how difficult would it be to generate in-line LLVM code for the write barrier, instead of calling a function? |
| 20:00:20 | evan | pretty easy |
| 20:00:42 | evan | you'd just detect when to emit it |
| 20:00:46 | evan | and emit it as LLVM IR |
| 20:00:49 | kstephens | is that something you have planned? |
| 20:00:56 | evan | sure. |
| 20:00:58 | evan | :) |
| 20:01:40 | kstephens | do you ignore mutations that store immediates? (Fixnums, etc?) |
| 20:02:07 | evan | when I can |
| 20:02:12 | kstephens | cool. |
| 20:02:19 | evan | the write_barrier has code to ignore immediates later on |
| 20:02:26 | evan | so they never get to the real meat |
| 20:03:36 | kstephens | reference & 1 => Fixnum? |
| 20:03:39 | kstephens | like MIR? |
| 20:03:42 | evan | yeah |
| 20:03:45 | evan | check out oop.hpp |
| 20:03:46 | kstephens | s/MIR/MRI/ |
| 20:03:57 | evan | all the rules are in there |
| 20:04:03 | kstephens | great, great! |
| 20:16:59 | evan | oop |
| 20:17:01 | evan | woop! |
| 20:17:07 | evan | all tags removed for Numeric. |
| 20:17:22 | brixen | sweet! |
| 20:21:14 | boyscout | Remove Range tags - 86fe1ee - Evan Phoenix |
| 20:21:14 | boyscout | Fix Method#name to return a String - d309394 - Evan Phoenix |
| 20:21:14 | boyscout | Fix coercion of the argument to Kernel.exit - d423726 - Evan Phoenix |
| 20:21:14 | boyscout | Remove some Numeric tags - cf92226 - Evan Phoenix |
| 20:21:14 | boyscout | More Numeric tower revisement - cdbd761 - Evan Phoenix |
| 20:21:15 | boyscout | Finish cleaning up Numeric failures - ad7a5eb - Evan Phoenix |
| 20:23:49 | evan | wtf |
| 20:24:00 | evan | why is there a random StringIO spec in io/print_spec.rb |
| 20:24:17 | brixen | who knows |
| 20:24:29 | evan | ok, i'm deleteting it. |
| 20:24:49 | evan | i'm double checking the blame |
| 20:25:02 | brixen | which spec? |
| 20:25:34 | brixen | this whole file is all kinds of what the fuck why do I try?! |
| 20:25:36 | brixen | goddamn |
| 20:26:02 | evan | :/ |
| 20:26:03 | evan | http://github.com/rubyspec/rubyspec/commit/71bcaf058c7ddaf3cdb3452e950e8a286df13dde |
| 20:26:30 | evan | he completely changed WHAT was being spec'd. |
| 20:26:33 | evan | :/ |
| 20:26:57 | brixen | yeah |
| 20:27:36 | rue | Valid reason for the change, probably, but a...sub-optimal implementation :P |
| 20:27:48 | evan | well |
| 20:27:52 | evan | but it's a spec for IO#print |
| 20:27:57 | evan | and the spec doesn't call IO#print... |
| 20:28:05 | brixen | right |
| 20:28:23 | rue | Yes, it would be wrong even if StringIO < IO, which it is not :) |
| 20:28:34 | evan | exactly. |
| 20:28:51 | evan | i'm checking the behavior on MRI now |
| 20:28:56 | evan | and i'll rewrite this test. |
| 20:29:00 | brixen | this spec should use ruby_exe instead of any mock |
| 20:30:46 | boyscout | CI: rubinius: ad7a5eb successful: 3024 files, 11791 examples, 36079 expectations, 0 failures, 0 errors |
| 20:31:10 | evan | so, it appears that IO#print calls IO#write, which should call #to_s and if the result is not a String, then uses rb_any_to_s |
| 20:31:22 | evan | which is the "#<0x... class>" thing |
| 20:32:07 | evan | brixen: should I use the output matcher? |
| 20:32:50 | rue | The output matcher is just for actual output, unless it was changed |
| 20:33:54 | evan | o = mock('o') |
| 20:33:54 | evan | o.should_not_receive(:to_str) |
| 20:33:56 | evan | o.should_receive(:to_s).and_return("hello") |
| 20:33:58 | evan | lambda { $stdout.print(o) }.should output("hello#{$\}") |
| 20:34:00 | evan | that passes |
| 20:34:13 | brixen | ok |
| 20:34:19 | evan | that ok? |
| 20:34:41 | brixen | I think it should use ruby_exe, but I'm looking at output matcher now |
| 20:34:59 | brixen | I'd rather it not have anything in the path of IO#print |
| 20:35:36 | brixen | the output matcher uses IOStub |
| 20:35:39 | evan | well, this is IO#print, so i can print to a tempfile or something |
| 20:35:48 | evan | no need to use $stdout |
| 20:36:05 | evan | in fact, this jumps through hoops to use $stdout |
| 20:36:31 | brixen | you can just use ruby_exe and compare on the output |
| 20:36:47 | brixen | which will more naturally use $stdout |
| 20:36:47 | evan | do you have an example i can look at? |
| 20:37:06 | brixen | ruby_exe("some code").should something |
| 20:37:12 | brixen | ack ruby_exe ;) |
| 20:37:24 | evan | is that better than the output matcher? |
| 20:37:36 | brixen | well, output matcher uses IOStub |
| 20:37:40 | evan | seems like launching another process is less elegant than using output matcher |
| 20:37:46 | evan | I don't know what IOStub is. |
| 20:37:57 | brixen | it's an object that fakes an IO |
| 20:38:04 | brixen | but we are testing an IO method |
| 20:38:07 | evan | oh |
| 20:38:10 | evan | eeeeww |
| 20:38:13 | evan | ok |
| 20:38:14 | brixen | seems silly to say we are testing it while using a fake |
| 20:38:19 | evan | why not a tempfile? |
| 20:38:31 | brixen | hence, ruby_exe("print something").should == "something" |
| 20:38:31 | evan | yeah, we clearly can't use the output matcher |
| 20:38:34 | brixen | or a tmp file |
| 20:38:38 | evan | it's completely changing what we're specing |
| 20:38:42 | brixen | right |
| 20:38:46 | brixen | that was my point |
| 20:38:53 | brixen | you can use a tmp file |
| 20:38:57 | evan | what about this output_to_fd() matcher |
| 20:39:07 | evan | does that use IOStub too? |
| 20:39:19 | brixen | it writes to a tmp file |
| 20:40:08 | evan | ok, it uses a reopen trick. |
| 20:40:18 | evan | is there an easy way to use a temp file? |
| 20:40:21 | brixen | it already does |
| 20:40:35 | brixen | look at mspec/lib/mspec/matchers/output_to_fd.rb |
| 20:40:38 | evan | all the reopen tricks aren't needed |
| 20:40:41 | brixen | I think that's all you'd want to do |
| 20:40:44 | evan | can i just use tmp() ? |
| 20:40:47 | brixen | yes |
| 20:40:54 | evan | and they'll get cleaned up automatically? |
| 20:40:58 | brixen | no |
| 20:41:20 | evan | ok |
| 20:41:28 | evan | well do they atleast go in the right directory? |
| 20:41:45 | brixen | let me write the spec |
| 20:41:53 | evan | no let me! |
| 20:41:55 | evan | you write too many! |
| 20:42:01 | brixen | this is "does not call obj.to_str" ? |
| 20:42:14 | evan | yeah |
| 20:42:16 | brixen | k |
| 20:42:24 | evan | ok, i'll get it right |
| 20:42:28 | evan | i see what to do |
| 20:42:34 | brixen | so you need a file name: name = tmp("io_print") |
| 20:42:46 | evan | you know what would be awesome? |
| 20:42:49 | brixen | but you need to delete it |
| 20:43:01 | evan | if tmp took a block and did File.unlink on it in an ensure |
| 20:43:25 | brixen | hm |
| 20:44:01 | brixen | often one name is used multiple times though |
| 20:44:13 | evan | ok, no prob. |
| 20:45:28 | brixen | http://gist.github.com/288138 |
| 20:45:45 | brixen | tmp() just returns a filename |
| 20:45:59 | brixen | you can open it or do whatever you want |
| 20:46:22 | brixen | touch(name, mode="w") takes an optional block |
| 20:46:45 | evan | https://gist.github.com/cfce939506c25ba8c225 |
| 20:47:08 | brixen | no begins and ensures in specs |
| 20:47:14 | evan | ok.. |
| 20:47:15 | brixen | that's what before/after actions are for |
| 20:47:36 | evan | k |
| 20:47:42 | brixen | all that extra stuff to tmp() is unnecessary |
| 20:47:50 | brixen | just tmp("io_print") |
| 20:49:57 | evan | https://gist.github.com/e8570700096db43f5548 |
| 20:50:01 | brixen | you could do touch(@name) { |f| f.print o } |
| 20:50:55 | brixen | this seems more complicated that it needs to be |
| 20:51:07 | evan | ok |
| 20:51:09 | evan | really? |
| 20:51:10 | brixen | hmm |
| 20:51:11 | evan | not to me. |
| 20:51:23 | evan | put the data in the temp file |
| 20:51:25 | brixen | not just this one spec, the process |
| 20:51:28 | evan | read it back out and check that it's what you expect. |
| 20:51:35 | brixen | right |
| 20:51:40 | brixen | well, that's what output_to_fd does |
| 20:51:57 | evan | but you need an IO to do that already |
| 20:52:05 | evan | and using $stdout is needless |
| 20:52:14 | evan | output_to_fd depends no IO#reopen |
| 20:52:22 | evan | and it's trivial to avoid having that dependency |
| 20:52:39 | evan | s/depends no/depends on/ |
| 20:52:54 | brixen | one sec |
| 20:55:30 | brixen | evan: I just pushed to your gist |
| 20:56:03 | evan | ok, so just use IO.read |
| 20:56:12 | brixen | touch and rm_r, yes |
| 20:56:42 | evan | ok, cool |
| 20:56:44 | evan | i'll commit this |
| 20:56:48 | brixen | k |
| 20:57:16 | Defiler | There's not a File method that means 'this process could create a file in the given directory', right? |
| 20:57:39 | evan | access is the method in C |
| 20:57:45 | brixen | evan: I think the block form of tmp() would be good for these type of IO specs |
| 20:57:54 | evan | brixen: yep. |
| 20:58:02 | evan | Defiler: i'm not sure access() is exposed |
| 20:58:05 | brixen | evan: maybe even redoing output matcher to use that |
| 20:58:12 | evan | cool |
| 20:58:46 | brixen | grabbing some lunch, I'll look at that after |
| 21:00:05 | evan | ditto. |
| 21:10:14 | boyscout | Fix IO#print spec to actually test IO#print - 86fb947 - Evan Phoenix |
| 21:10:14 | boyscout | Remove IO#print tags - d0f1971 - Evan Phoenix |
| 21:10:14 | boyscout | Cleanup the IO#print specs - 4f2bc22 - Evan Phoenix |
| 21:10:58 | rue | Oh, I thought #output was #output_to_fd |
| 21:12:30 | rue | Going through File is not necessarily a good idea if trying to test IO |
| 21:13:13 | evan | much better than depending on IO#reopen |
| 21:13:14 | evan | imho. |
| 21:13:47 | rue | I disagree, provided #reopen can be specified. Only circular dependencies are bad |
| 21:14:10 | boyscout | CI: rubinius: 4f2bc22 successful: 3024 files, 11791 examples, 36082 expectations, 0 failures, 0 errors |
| 21:15:11 | rue | Then again File and IO have virtually no proper separation so it is somewhat academic. |
| 21:16:36 | evan | anyway, lunch. |
| 21:26:28 | dbussink | evan: are you ok with some helper method on a string that basicly cuts x bytes off by decreasing @num_bytes and @characters? |
| 21:59:56 | evan | dbussink: why does that need to be a method? |
| 22:00:06 | evan | just do @num_bytes -= total |
| 22:00:11 | evan | i should just remove @characters. |
| 22:00:14 | evan | we've never use dit. |
| 22:13:46 | evan | man |
| 22:14:03 | evan | people really need to take more than 1 second in naming and grouping their it blocks |
| 22:14:06 | evan | geez. |
| 22:22:18 | brixen | indeed |
| 22:27:44 | Zoxc | wants a function to get the real name of a file on a case insensitive filesystem :( |
| 22:28:14 | evan | use ls. |
| 22:28:19 | evan | or just read the dir |
| 22:28:49 | Zoxc | doesn't know how to read the file stations on Windows |
| 22:28:55 | evan | Dir["#{path}/*"].find { |i| i.downcase == orig.downcase } |
| 22:34:39 | Zoxc | I wrote this thing: http://pastie.org/797847 |
| 22:34:50 | Zoxc | which only works for relative paths |
| 22:38:48 | evan | fun |
| 22:40:25 | Zoxc | and I cleaned it up ^^ http://pastie.org/797858 |
| 22:40:54 | evan | you probably just need File.expand_path |
| 22:40:56 | evan | rather than using Pathname |
| 22:41:05 | evan | File.expand_path cleans up the path pretty darn well. |
| 22:41:25 | Zoxc | yeah, that will probably be faster |
| 22:41:35 | Zoxc | then I only got to convert into a relative path again :D |
| 22:41:46 | evan | oh |
| 22:41:50 | evan | File.expand_path does that too |
| 22:41:59 | evan | File.expand_path(dir, Dir.getwd) |
| 22:42:50 | Zoxc | no, it just use that other parameter as the current directory |
| 22:43:13 | evan | m, yes. |
| 22:43:15 | evan | my mistake. |
| 22:43:41 | kronos_vano | http://isitruby19.com/ may be clone it for rubinius? "isitrubinius.com" :D |
| 22:44:07 | evan | if you want, sure. |
| 23:20:39 | yakischloba | they should be a single site :/ |
| 23:21:15 | evan | i wouldn't argue with that either. |
| 23:22:31 | yakischloba | i duno why there should be 3 identical sites instead of just listing compatibility and sorting comments per ruby implementation |
| 23:35:12 | evan | ok, finally implemented IO#ungetc |
| 23:35:22 | evan | there is one failing spec that i'm going to leave failing |
| 23:35:28 | evan | it's stupid. |
| 23:37:11 | lopex | isitruby186p342.com ? |
| 23:37:48 | brixen | evan: which? |
| 23:38:06 | evan | not the spec, the behavior. |
| 23:38:18 | brixen | yeah, curious which it is |
| 23:38:21 | evan | it's a bug in 1.8 |
| 23:38:24 | evan | that is fixed in 1.9 |
| 23:38:28 | evan | it "raises IOError when invoked on stream that was not yet read" |
| 23:38:29 | brixen | ah |
| 23:38:47 | evan | in 1.8, you can't call #ungetc until you've called #read at least once. |
| 23:38:52 | evan | which is dumb. |
| 23:38:53 | brixen | should be probably be a ruby_bug then |
| 23:38:56 | brixen | fixed in 1.9 |
| 23:39:03 | evan | k |
| 23:39:04 | evan | ok |
| 23:39:33 | brixen | hmm yeah |
| 23:39:44 | brixen | I would have made this a ruby_bug instead of ruby_version_is |
| 23:39:56 | brixen | but then, probably pointless to file a bug ticket on 1.8 |
| 23:39:57 | brixen | :/ |
| 23:40:10 | evan | so given that it's changed in 1.9 |
| 23:40:21 | evan | do i need to find down a ruby-core bug number or anything? |
| 23:40:37 | brixen | well, that's what I mean, they probably will just ignore it |
| 23:40:38 | brixen | like http://redmine.ruby-lang.org/issues/show/2578 |
| 23:40:41 | brixen | so dunno |
| 23:40:51 | brixen | might as well file a ticket |
| 23:41:03 | brixen | there's no reason that should be not considered a bug, would you say? |
| 23:41:19 | evan | well, lets see. |
| 23:42:46 | brixen | hm, I wonder... |
| 23:42:46 | evan | so |
| 23:42:54 | evan | i'm betting this was not a "bug" |
| 23:42:59 | evan | so much as they fixed the behavior in 1.9 |
| 23:43:04 | evan | because 1.9 has it's own buffer code |
| 23:43:15 | evan | it's not just using FILE's stdio functions |
| 23:43:31 | brixen | that's just what I was wondering |
| 23:43:49 | brixen | looking at man ungetc, i don't see whether it fails if *stream had not been read |
| 23:44:11 | evan | surprise! |
| 23:44:13 | brixen | it says it allows as much pushback as there is sufficient memory |
| 23:45:00 | evan | yeah |
| 23:45:09 | evan | well, it doesn't. :) |
| 23:45:15 | evan | it's an edge case. |
| 23:45:21 | evan | where there is no back buffer allocated yet |
| 23:45:22 | evan | i think. |
| 23:46:54 | brixen | hmm |
| 23:47:11 | brixen | "The file-position indicator is decremented by each successful call to ungetc(); if its value was 0 before a call, its value is unspecified after the call." |
| 23:47:43 | evan | *shrug* |
| 23:48:01 | evan | MRI's IO#ungetc in 1.8 is a very thin wrapper around ungetc |
| 23:48:25 | brixen | yeah, I get EOF doing ungetc on a stream I haven't read from |
| 23:48:37 | evan | oh actually.. i wonder if it's this first condition in 1.8 |
| 23:48:43 | evan | if (!(fptr->mode & FMODE_RBUF)) |
| 23:48:55 | evan | i'll bet it is |
| 23:49:17 | evan | yeah, that this code just sucks |
| 23:49:26 | evan | because RBUF mode is set by a bunch of random things |
| 23:49:31 | evan | including by a bunch of read methods |
| 23:49:37 | evan | so it's a bad edge case. |
| 23:50:02 | brixen | hm, I was wrong |
| 23:50:06 | brixen | I was using an empty file |
| 23:50:19 | brixen | I just opened a non-empty file and did ungetc without reading |
| 23:50:45 | brixen | the next read get the char I ungetc'd |
| 23:51:07 | evan | it blocks named like |
| 23:51:09 | evan | it "can handle any numerical argument without breaking" do |
| 23:51:11 | brixen | so this is just a wonky 1.8 behavior resulting from its weird way of implementing IO |
| 23:51:14 | evan | not very useful. |
| 23:51:22 | brixen | yeah, love those specs |
| 23:51:27 | brixen | it "works" do |
| 23:51:30 | brixen | mmkay |
| 23:52:01 | brixen | hm, I hate cases like this... |
| 23:52:28 | brixen | on the one hand, it's a totally useless spec because is any app code going to depend on *failing* in this particular way? |
| 23:52:44 | brixen | on the other hand, it's a difference between 1.8 and 1.9 |
| 23:52:59 | brixen | I'd say rm the 1.8 spec and leave the 1.9 one |
| 23:53:16 | evan | k |
| 23:53:24 | brixen | what do you think? |
| 23:53:47 | evan | seems logical to me |
| 23:54:08 | evan | wait |
| 23:54:09 | brixen | alternatively, we could file a bug on 1.8 |
| 23:54:13 | evan | aren't IO#seek and IO#pos= the same? |
| 23:54:33 | brixen | i thought so |
| 23:54:44 | evan | hah |
| 23:54:47 | evan | so in MRI |
| 23:54:53 | evan | they're 2 different functions |
| 23:54:57 | evan | with pretty much the same code in them. |
| 23:55:03 | brixen | well, #seek can take a WHENCE |
| 23:55:05 | brixen | arg |
| 23:55:33 | brixen | #pos= is like #seek(off, SEEK_SET) |
| 23:55:35 | brixen | I think |
| 23:55:37 | evan | yep. |
| 23:58:53 | evan | IO#pos= and IO#seek almost need a shared spec |
| 23:59:01 | evan | because the same person seems to have written them |
| 23:59:09 | evan | but they got better as they went on |
| 23:59:17 | evan | so the pos= ones are slightly better. |
| 23:59:23 | evan | but they're basically the same |
| 23:59:27 | evan | i'm going to at least fix them box |
| 23:59:29 | evan | both |