7 |
8 |
9 |
--------------------------------------------------------------------------------
/doc/README_FOR_APP:
--------------------------------------------------------------------------------
1 | Use this README file to introduce your application and point to useful places in the API for learning more.
2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-Agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Sample localization file for English. Add more files in this directory for other locales.
2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 |
4 | en:
5 | hello: "Hello world"
6 |
--------------------------------------------------------------------------------
/test/functional/index_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class IndexControllerTest < ActionController::TestCase
4 | test "should get terminal" do
5 | get :terminal
6 | assert_response :success
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/test/functional/tutorials_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class TutorialsControllerTest < ActionController::TestCase
4 | test "should get intro" do
5 | get :intro
6 | assert_response :success
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 | require 'rake'
6 |
7 | Tryruby::Application.load_tasks
8 |
--------------------------------------------------------------------------------
/test/performance/browsing_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 | require 'rails/performance_test_help'
3 |
4 | # Profiling results for each test method are written to tmp/performance.
5 | class BrowsingTest < ActionDispatch::PerformanceTest
6 | def test_homepage
7 | get '/'
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
7 | # Mayor.create(:name => 'Daley', :city => cities.first)
8 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Tryruby::Application.config.session_store :cookie_store, :key => '_tryruby_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # Tryruby::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## TryRuby! version 2 (Obsolete)
2 | This is the Source code to the TryRuby! version 2.
3 | If you want to see the original running TryRuby! version 2 code, then checkout the legacy branch.
4 | ## This codebase is obsolete. Thankfully a new version lives on in TryRuby! version 4 which is based on opalrb.
5 |
6 | Version 4 of TryRuby! lives at
7 | https://github.com/easydatawarehousing/tryruby
8 |
9 | The link to the live site is https://ruby.github.io/TryRuby/
10 |
--------------------------------------------------------------------------------
/app/views/irb/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(@irb) do |f| %>
2 | <% if @irb.errors.any? %>
3 |
4 |
<%= pluralize(@irb.errors.count, "error") %> prohibited this irb from being saved:
5 |
6 |
7 | <% @irb.errors.full_messages.each do |msg| %>
8 |
18 |
19 |
20 |
21 | <%= link_to 'New Irb', new_irb_path %>
22 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | ENV["RAILS_ENV"] = "test"
2 | require File.expand_path('../../config/environment', __FILE__)
3 | require 'rails/test_help'
4 |
5 | class ActiveSupport::TestCase
6 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7 | #
8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests
9 | # -- they do not yet inherit this setting
10 | fixtures :all
11 |
12 | # Add more helper methods to be used by all tests here...
13 | end
14 |
--------------------------------------------------------------------------------
/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | Tryruby::Application.config.secret_token = '0b9697ad5c8979de943825eeb25418d1f8cf963ad4e3a6758acc2558ae77b0c097997142fea5c9cb5969f2126ee433aefccbae922c04943ca4074d2c31e9c608'
8 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 |
3 | def google_analytics_js
4 | ua_code = "UA-2365371-3"
5 | ''
15 |
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 |
2 | development:
3 | adapter: mysql2
4 | database: tryruby_development
5 | username: root
6 | password:
7 | pool: 5
8 | timeout: 5000
9 | host: 127.0.0.1
10 |
11 | # Warning: The database defined as "test" will be erased and
12 | # re-generated from your development database when you run "rake".
13 | # Do not set this db to the same as development or production.
14 | test:
15 | adapter: mysql2
16 | database: tryruby_test
17 | username: root
18 | password:
19 | pool: 5
20 | timeout: 5000
21 | host: 127.0.0.1
22 |
23 | production:
24 | adapter: mysql2
25 | database: tryruby_production
26 | username: root
27 | password:
28 | pool: 5
29 | timeout: 5000
30 | host: localhost
31 | cucumber:
32 | <<: *test
33 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The change you wanted was rejected.
23 |
Maybe you tried to change something you didn't have access to.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The page you were looking for doesn't exist.
23 |
You may have mistyped the address or the page may have moved.
First, I'd like to thank the over 365,345 (three hundred sixty five thousand three hundred fourty five) people who have used Try Ruby (globally) over 508,600 (five hundred eight thousand six hundred) times in the last two years!
17 |
It has been an honor and a privlege to help restore such a fantastic resource.
18 |
Because of the fun nature of Try Ruby, it only makes sense to allow it to reach its full potential.
19 |
Specifically, Try Ruby must have lessons for the full language.
20 |
A partial list includes
21 |
22 |
Blocks, Lambdas, Closures, and Procs
23 |
Object Model (DrX with a live svg front end)
24 |
Metaprogramming
25 |
Sandboxing
26 |
Standard lib
27 |
Unit Testing & Outside in Behavior Driven Development
28 |
The Ruby VM (Garbage Collection, Tuning, etc)
29 |
Try Ruby Offline & Mobile versions.
30 |
31 |
32 |
I have gladly covered the hosting expense (currently amazon ec2 small instance, and before that a dedicated box) for the last two years.
33 | The smile people have when experiencing the beauty of Ruby has been more than worth it. :-)
34 |
However, in order allow Try Ruby's potential to flourish- muchless stay online- I am currently raising funds. I have never placed ads or sold any information collected by Try Ruby. Please donate to help this site reach its full potential.
35 |
If all goes well, I will have weekly lessons, much in the spirit of Railscasts. Obviously these would be interative lessons.
36 |
Last, I'd like to thank David Miani for helping me reassemble Try Ruby when _why disappeared*. Also, a thanks goes out to Adrian aka "Orangea" for his eairly work in finding security holes and helping with other misc issues. A deep thanks also goes out to everyone who has ever reported a bug or issue with Try Ruby.
37 |
Thank You.
38 | Respectfully,
39 | Andrew McElroy
40 |
* _why the lucky stiff was the origional creator of Try Ruby. However he vanished from the Internet over two years ago. He took his copy of Try Ruby with him. We had to completely reimplement Try Ruby.
Ruby es un lenguaje de programación de Japón
38 | (disponible en ruby-lang.org)
39 | que está revolucionando la web.
40 | La belleza de Ruby se encuentra en su balance entre la simplicidad y el poder.
41 |
42 |
Prueba código Ruby en el prompt de arriba. Además de los métodos
43 | originales de Ruby, los siguientes comandos están disponibles:
44 |
45 |
help
46 | Empieza el tutorial interactivo de 15 minutos. ¡Creeme, es muy básico!
47 |
help 2
48 | Salta al capítulo 2.
49 |
50 |
clear
51 | Limpia la pantalla. Útil si tu navegador empieza a alerdarce.
52 | Tu historial de comandos será recordado.
53 |
back
54 | Retrocede una pantalla en el tutorial.
55 |
reset
56 | Resetea el interprete. (o Ctrl-D!)
57 |
next
58 | Te permite saltear la siguiente lección
59 |
60 |
time
61 | Detiene el reloj. Imprime cuanto tiempo tu sesión estuvo abierta.
62 |
63 |
Si te pasa de dejar o refrescar la página, tu sesión seguirá aquí a menos que
64 | se deje inactiva por diez minutos.
65 |
66 |
67 |
68 |
69 |
70 |
¿Atrapado en los dos puntos? Unas comillas o algo fue dejado abierto. Escribe: reset o aprieta Ctrl-D.
71 |
72 |
73 |
This place was sired by why the lucky stiff.
74 | Please contact me using the email address at that link.is maintained by Andrew McElroy and David Miani. For support issues, please post a ticket or contact Sophrinix on github. Por asuntos de traducción, mandar un ticket o contactarse con Cristian Re (leizzer) en Github.
75 |
72 | Welcome to your first taste of Haskell! Let's try Haskell right now!
73 |
74 |
Beginners
75 |
76 |
Type help to start the
77 | tutorial. Type lessons to see the
78 | list of lessons.
79 |
Or try typing these out and see what happens
80 | (click to insert):
81 |
82 |
83 | 23*36
84 |
85 |
86 | reverse "hello"
87 |
88 |
89 |
90 |
91 |
Learn More
92 |
93 |
94 | Real World Haskell!
97 | Get stuck into a book with
98 | Real
99 | World Haskell
100 | (readable online!), published by O'Reilly Media.
101 | Checkout
102 | Haskell.org
104 | for more information about Haskell.
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/public/javascripts/mouseirb_2.js:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2008 why the lucky stiff
3 | //
4 | // Permission is hereby granted, free of charge, to any person
5 | // obtaining a copy of this software and associated documentation
6 | // files (the "Software"), to deal in the Software without restriction,
7 | // including without limitation the rights to use, copy, modify, merge,
8 | // publish, distribute, sublicense, and/or sell copies of the Software,
9 | // and to permit persons to whom the Software is furnished to do so,
10 | // subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16 | // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18 | // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19 | // SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21 | // OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | /* Irb running moush */
27 | MouseApp.Irb = function(element, options) {
28 | this.element = $(element);
29 | this.setOptions(options);
30 | this.showHelp = this.options.showHelp;
31 | if ( this.options.showChapter ) {
32 | this.showChapter = this.options.showChapter;
33 | }
34 | if ( this.options.init ) {
35 | this.init = this.options.init;
36 | }
37 | this.initWindow();
38 | this.setup();
39 | this.helpPage = null;
40 | this.irbInit = false;
41 | };
42 |
43 | $.extend(MouseApp.Irb.prototype, MouseApp.Terminal.prototype, {
44 | cmdToQuery: function(cmd) {
45 | return "cmd=" + escape(cmd.replace(/</g, '<').replace(/>/g, '>').
46 | replace(/&/g, '&').replace(/\r?\n/g, "\n")).replace(/\+/g, "%2B");
47 | },
48 |
49 | fireOffCmd: function(cmd, func) {
50 | var irb = this;
51 | if (!this.irbInit)
52 | {
53 | $.ajax({url: this.options.irbUrl + "?" + this.cmdToQuery("!INIT!IRB!"), type: "GET",
54 | complete: (function(r) { irb.irbInit = true; irb.fireOffCmd(cmd, func); })});
55 | }
56 | else
57 | {
58 | $.ajax({url: this.options.irbUrl + "?" + this.cmdToQuery(cmd), type: "GET",
59 | complete: func});
60 | }
61 | },
62 |
63 | reply: function(str) {
64 | var raw = str.replace(/\033\[(\d);(\d+)m/g, '');
65 | this.checkAnswer(raw);
66 | if (!str.match(/^(\.\.)+$/)) {
67 | if ( str[str.length - 1] != "\n" ) {
68 | str += "\n";
69 | }
70 | js_payload = /\033\[1;JSm(.*)\033\[m/;
71 | js_in = str.match(js_payload);
72 | if (js_in) {
73 | try {
74 | js_in = eval(js_in[1]);
75 | } catch (e) {}
76 | str = str.replace(js_payload, '');
77 | }
78 | var pr_re = new RegExp("(^|\\n)=>");
79 | if ( str.match( pr_re ) ) {
80 | str = str.replace(new RegExp("(^|\\n)=>"), "$1\033[1;34m=>\033[m");
81 | } else {
82 | str = str.replace(new RegExp("(^|\\n)= (.+?) ="), "$1\033[1;33m$2\033[m");
83 | }
84 | this.write(str);
85 | this.prompt();
86 | } else {
87 | this.prompt("\033[1;32m" + ".." + "\033[m", true);
88 | this.puts(str.replace(/\./g, ' '), 0);
89 | }
90 | },
91 |
92 | setHelpPage: function(n, page) {
93 | if (this.helpPage)
94 | $(this.helpPage.ele).hide('fast');
95 | this.helpPage = {index: n, ele: page};
96 | match = this.scanHelpPageFor('load');
97 | if (match != -1)
98 | {
99 | this.fireOffCmd(match, (function(r) {
100 | $(page).show('fast');
101 | }));
102 | }
103 | else
104 | {
105 | $(page).show('fast');
106 | }
107 | },
108 |
109 | scanHelpPageFor: function(eleClass) {
110 | match = $("div." + eleClass, this.helpPage.ele);
111 | if ( match[0] ) return match[0].innerHTML;
112 | else return -1;
113 | },
114 |
115 | checkAnswer: function(str) {
116 | if ( this.helpPage ) {
117 | match = this.scanHelpPageFor('answer');
118 | if ( match != -1 ) {
119 | if ( str.match( new RegExp('^\s*=> ' + match + '\s*$', 'm') ) ) {
120 | this.showHelp(this.helpPage.index + 1);
121 | }
122 | } else {
123 | match = this.scanHelpPageFor('stdout');
124 | if ( match != -1 ) {
125 | if ( match == '' ) {
126 | if ( str == '' || str == null ) this.showHelp(this.helpPage.index + 1);
127 | } else if ( str.match( new RegExp('^\s*' + match + '$', 'm') ) ) {
128 | this.showHelp(this.helpPage.index + 1);
129 | }
130 | }
131 | }
132 | }
133 | },
134 |
135 | onKeyCtrld: function() {
136 | this.clearCommand();
137 | this.puts("reset");
138 | this.onKeyEnter();
139 | },
140 |
141 | onKeyEnter: function() {
142 | this.typingOff();
143 | var cmd = this.getCommand();
144 | if (cmd) {
145 | this.history[this.historyNum] = cmd;
146 | this.backupNum = ++this.historyNum;
147 | }
148 | this.commandNum++;
149 | this.advanceLine();
150 | if (cmd) {
151 | if ( cmd == "clear" ) {
152 | this.clear();
153 | this.prompt();
154 | } else if ( cmd.match(/^(back)$/) ) {
155 | if (this.helpPage && this.helpPage.index >= 1) {
156 | this.showHelp(this.helpPage.index - 1);
157 | }
158 | this.prompt();
159 | } else if ( cmd.match(/^(next)$/) ) {
160 | if (this.helpPage) {
161 | this.showHelp(this.helpPage.index + 1);
162 | }
163 | this.prompt();
164 | } else if ( cmd.match(/^(help|wtf\?*)$/) ) {
165 | this.showHelp(1);
166 | this.prompt();
167 | } else if ( regs = cmd.match(/^(help|wtf\?*)\s+#?(\d+)\s*$/) ) {
168 | this.showChapter(parseInt(regs[2]));
169 | this.prompt();
170 | } else {
171 | var term = this;
172 | this.fireOffCmd(cmd, (function(r) { term.reply(r.responseText ? r.responseText : ''); }));
173 | }
174 | } else {
175 | this.prompt();
176 | }
177 | }
178 | });
179 |
180 |
--------------------------------------------------------------------------------
/public/javascripts/rails.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | // Technique from Juriy Zaytsev
3 | // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4 | function isEventSupported(eventName) {
5 | var el = document.createElement('div');
6 | eventName = 'on' + eventName;
7 | var isSupported = (eventName in el);
8 | if (!isSupported) {
9 | el.setAttribute(eventName, 'return;');
10 | isSupported = typeof el[eventName] == 'function';
11 | }
12 | el = null;
13 | return isSupported;
14 | }
15 |
16 | function isForm(element) {
17 | return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18 | }
19 |
20 | function isInput(element) {
21 | if (Object.isElement(element)) {
22 | var name = element.nodeName.toUpperCase()
23 | return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24 | }
25 | else return false
26 | }
27 |
28 | var submitBubbles = isEventSupported('submit'),
29 | changeBubbles = isEventSupported('change')
30 |
31 | if (!submitBubbles || !changeBubbles) {
32 | // augment the Event.Handler class to observe custom events when needed
33 | Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34 | function(init, element, eventName, selector, callback) {
35 | init(element, eventName, selector, callback)
36 | // is the handler being attached to an element that doesn't support this event?
37 | if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38 | (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39 | // "submit" => "emulated:submit"
40 | this.eventName = 'emulated:' + this.eventName
41 | }
42 | }
43 | )
44 | }
45 |
46 | if (!submitBubbles) {
47 | // discover forms on the page by observing focus events which always bubble
48 | document.on('focusin', 'form', function(focusEvent, form) {
49 | // special handler for the real "submit" event (one-time operation)
50 | if (!form.retrieve('emulated:submit')) {
51 | form.on('submit', function(submitEvent) {
52 | var emulated = form.fire('emulated:submit', submitEvent, true)
53 | // if custom event received preventDefault, cancel the real one too
54 | if (emulated.returnValue === false) submitEvent.preventDefault()
55 | })
56 | form.store('emulated:submit', true)
57 | }
58 | })
59 | }
60 |
61 | if (!changeBubbles) {
62 | // discover form inputs on the page
63 | document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64 | // special handler for real "change" events
65 | if (!input.retrieve('emulated:change')) {
66 | input.on('change', function(changeEvent) {
67 | input.fire('emulated:change', changeEvent, true)
68 | })
69 | input.store('emulated:change', true)
70 | }
71 | })
72 | }
73 |
74 | function handleRemote(element) {
75 | var method, url, params;
76 |
77 | var event = element.fire("ajax:before");
78 | if (event.stopped) return false;
79 |
80 | if (element.tagName.toLowerCase() === 'form') {
81 | method = element.readAttribute('method') || 'post';
82 | url = element.readAttribute('action');
83 | params = element.serialize();
84 | } else {
85 | method = element.readAttribute('data-method') || 'get';
86 | url = element.readAttribute('href');
87 | params = {};
88 | }
89 |
90 | new Ajax.Request(url, {
91 | method: method,
92 | parameters: params,
93 | evalScripts: true,
94 |
95 | onComplete: function(request) { element.fire("ajax:complete", request); },
96 | onSuccess: function(request) { element.fire("ajax:success", request); },
97 | onFailure: function(request) { element.fire("ajax:failure", request); }
98 | });
99 |
100 | element.fire("ajax:after");
101 | }
102 |
103 | function handleMethod(element) {
104 | var method = element.readAttribute('data-method'),
105 | url = element.readAttribute('href'),
106 | csrf_param = $$('meta[name=csrf-param]')[0],
107 | csrf_token = $$('meta[name=csrf-token]')[0];
108 |
109 | var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110 | element.parentNode.insert(form);
111 |
112 | if (method !== 'post') {
113 | var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114 | form.insert(field);
115 | }
116 |
117 | if (csrf_param) {
118 | var param = csrf_param.readAttribute('content'),
119 | token = csrf_token.readAttribute('content'),
120 | field = new Element('input', { type: 'hidden', name: param, value: token });
121 | form.insert(field);
122 | }
123 |
124 | form.submit();
125 | }
126 |
127 |
128 | document.on("click", "*[data-confirm]", function(event, element) {
129 | var message = element.readAttribute('data-confirm');
130 | if (!confirm(message)) event.stop();
131 | });
132 |
133 | document.on("click", "a[data-remote]", function(event, element) {
134 | if (event.stopped) return;
135 | handleRemote(element);
136 | event.stop();
137 | });
138 |
139 | document.on("click", "a[data-method]", function(event, element) {
140 | if (event.stopped) return;
141 | handleMethod(element);
142 | event.stop();
143 | });
144 |
145 | document.on("submit", function(event) {
146 | var element = event.findElement(),
147 | message = element.readAttribute('data-confirm');
148 | if (message && !confirm(message)) {
149 | event.stop();
150 | return false;
151 | }
152 |
153 | var inputs = element.select("input[type=submit][data-disable-with]");
154 | inputs.each(function(input) {
155 | input.disabled = true;
156 | input.writeAttribute('data-original-value', input.value);
157 | input.value = input.readAttribute('data-disable-with');
158 | });
159 |
160 | var element = event.findElement("form[data-remote]");
161 | if (element) {
162 | handleRemote(element);
163 | event.stop();
164 | }
165 | });
166 |
167 | document.on("ajax:after", "form", function(event, element) {
168 | var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169 | inputs.each(function(input) {
170 | input.value = input.readAttribute('data-original-value');
171 | input.removeAttribute('data-original-value');
172 | input.disabled = false;
173 | });
174 | });
175 |
176 | Ajax.Responders.register({
177 | onCreate: function(request) {
178 | var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
179 |
180 | if (csrf_meta_tag) {
181 | var header = 'X-CSRF-Token',
182 | token = csrf_meta_tag.readAttribute('content');
183 |
184 | if (!request.options.requestHeaders) {
185 | request.options.requestHeaders = {};
186 | }
187 | request.options.requestHeaders[header] = token;
188 | }
189 | }
190 | });
191 | })();
192 |
--------------------------------------------------------------------------------
/public/javascripts/console.js:
--------------------------------------------------------------------------------
1 | jQuery.fn.debug = function() {
2 | var msg = jqArray.args(arguments);
3 | $("").addClass("error").text(msg.join(", ")).prependTo(this);
4 | }
5 |
6 | jQConsole = function(input, output) {
7 |
8 | var args = jqArray.args
9 |
10 | var input = input;
11 |
12 | // History
13 | var command_history = [];
14 | var command_selected = 0;
15 |
16 | var local_scope = safe_scope();
17 |
18 | function hide_fn(fn) { return function() { return fn.apply(this, arguments); } }
19 | hide_fn.desc = "A function that creates a wrapper that hides the implementation of another function";
20 | function queue_fn(fn, time) { if(!time) time = 0; return function() { setTimeout(fn, time); } }
21 | queue_fn.desc = "Turns a function into a function that's called later";
22 |
23 | var keys = function (o) {
24 | var r = [];
25 | if (typeof o != "object") return r;
26 | for (var k in o) r.push(k);
27 | return r;
28 | }
29 | var refocus = queue_fn(function() { input.blur().focus(); });
30 | var reset_input = queue_fn(function() { input.val("").blur().focus(); });
31 | function no_recurse(fn, max_depth) {
32 | var count = 0;
33 | if(!max_depth) max_depth = 1;
34 | return function() {
35 | count++;
36 | if(count > max_depth) {
37 | count--; return;
38 | } else {
39 | fn.apply(this, arguments);
40 | }
41 | }
42 | }
43 |
44 | function hook_fn(fn, listener) {
45 | fn.listener = function() { return listener; }
46 | fn.apply = function(thisArg, argArray) {
47 | if(fn == caller) return;
48 | listener();
49 | return fn.apply(thisArg, argArray);
50 | };
51 | }
52 |
53 | hook_fn(history, function() { print("Yo"); });
54 |
55 | $(document).ready(page_onload);
56 |
57 | function page_onload() {
58 | input = $(input);
59 | output = $(output);
60 | input.keypress(map_keyboard());
61 | $(document).click(refocus);
62 | refocus();
63 | }
64 | page_onload = hide_fn(page_onload);
65 |
66 | function clear() { output.html(""); }
67 |
68 | function history() {
69 | return command_history.join("\n");
70 | }
71 |
72 | var keyLogging = false;
73 |
74 | function map_keyboard() {
75 | var cmdKeys = keymap();
76 | with(cmdKeys) {
77 | mapKeyCode(toggleKeyLogging, 120);
78 | map(executeCommand, {keyCode:13, ctrlKey:true});
79 | //mapKeyCode(executeCommand, 13);
80 | mapKeyCode(refocus, 9);
81 | map(historyLast, {keyCode:38, ctrlKey:true});
82 | map(historyNext, {keyCode:40, ctrlKey:true});
83 | map(function() { return false; }, {keyCode:123});
84 | }
85 | return function(e) {
86 | if(keyLogging)
87 | log("keyCode: " + e.keyCode, " shiftKey: " + e.shiftKey, " ctrlKey: " + e.ctrlKey);
88 | resize_input();
89 | return cmdKeys.dispatch(e);
90 | }
91 | }
92 |
93 | function toggleKeyLogging() { keyLogging = !keyLogging; }
94 |
95 | function historyLast() {
96 | command_selected = Math.max(0, command_selected - 1);
97 | edit_command(command_history[command_selected]);
98 | }
99 |
100 | function historyNext() {
101 | command_selected = Math.min(command_history.length, command_selected + 1);
102 | var cmd = (command_selected == command_history.length) ? "" : command_history[command_selected];
103 | edit_command(cmd);
104 | }
105 |
106 | function tryComplete() {
107 |
108 | refocus();
109 | }
110 |
111 | function executeCommand(cmd) {
112 | cmd = (!cmd) ? input.val() : cmd;
113 | reset_input();
114 | var result = evalInScope(cmd, default_scope);
115 | command_selected = command_history.length;
116 | logCommand(cmd, result);
117 | setTimeout(function() { input.attr("rows", 1); }, 2);
118 | return false;
119 | }
120 |
121 | function evalInScope(cmd, scope) {
122 | try {
123 |
124 | //if(!scope) return eval.apply(our_scope, [cmd]);
125 | with(scope) {
126 | with(jQConsole.our_scope) {
127 | return eval(cmd);
128 | }
129 | }
130 |
131 | //move_modified_scope(local_scope, global_scope);
132 | }
133 | catch(e) {
134 | return e.message;
135 | }
136 | }
137 |
138 | function move_modified_scope(l, g) {
139 |
140 | for(var k in g) {
141 | if(g[k] && typeof l[k] == 'undefined') {
142 | l[k] = g[k];
143 | g[k] = null;
144 | }
145 | }
146 | }
147 |
148 | function safe_scope() {
149 | var s = {}, g = jQConsole.global_scope;
150 | for(var k in g) { s[k] = null; }
151 | s.global_scope = jQConsole.global_scope;
152 | return s;
153 | }
154 |
155 | var encoders = {
156 | "object": function(o, l) {
157 | if(o.constructor == Array)
158 | return encode_array(o);
159 | //return "[array]";
160 | return "{ " + encode_obj(o, l) + " }";
161 | },
162 | "function": function(v) { return v.toString(); },
163 | "string": function(v) { return "\"" + v + "\""; },
164 | "undefined": function() { return "undefined"; },
165 | _default: function(v) { return v.toString(); }
166 | }
167 |
168 | function encode_array(a) {
169 | var r = a.map(enc);
170 | return "[" + r.join(",") + "]";
171 | }
172 |
173 | enc = function(v, l, root) {
174 | root = root || true;
175 | if(v == null) return (root) ? "" : "null" + l;
176 | if(encoders[typeof v]) return encoders[typeof v](v);
177 | //log("enc", v, l);
178 | return encoders._default(v, l);
179 | }
180 |
181 | function encode_obj(val, expand) {
182 | if(expand <= 0) { return val.toString(); }
183 | var r = [];
184 | for(var i in val) {
185 | r.push(i + ": " + enc(val[i], expand - 1, false));
186 | }
187 | return r.join(",\n");
188 | }
189 |
190 | function encode_reg(s) {
191 | return s.replace(/([\\/\t\n])/g, "\\$1");
192 | }
193 |
194 | function reg_lookup_fn(lookup) {
195 | var re = new RegExp(encode_reg(keys(lookup).join("")), "ig");
196 | return re;
197 | }
198 |
199 | function print(msg) {
200 | var className = (typeof msg == "function") ? "cmd" : "print";
201 | msg = enc(msg, 3);
202 | if(!msg) return;
203 | var out = $($.PRE({"className":className}, msg));
204 | if(className == "cmd") { out.click(select_command); }
205 | output.prepend(out);
206 | }
207 |
208 | function logCommand(cmd, result) {
209 | command_history.push(cmd);
210 | if(result != undefined) {
211 | output.prepend(jQuery.dump(result));
212 | }
213 | $($.PRE({className:'cmd'}, cmd)).click(select_command).prependTo(output);
214 | //print(result);
215 | return cmd;
216 | }
217 |
218 | function select_command() {
219 | edit_command($(this).text());
220 | }
221 |
222 | function edit_command(cmd) {
223 | input.val(cmd);
224 | resize_input();
225 | input.get(0).select();
226 | }
227 |
228 | function log() {
229 | var msg = args(arguments);
230 | $("").text(msg.join(", ")).prependTo(output);
231 | }
232 |
233 | function resize_input()
234 | {
235 | setTimeout(do_resize, 0);
236 |
237 | function do_resize() {
238 | var rows = input.val().split(/\n/).length
239 | // + 1 // prevent scrollbar flickering in Mozilla
240 | + (window.opera ? 1 : 0); // leave room for scrollbar in Opera
241 |
242 | // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.
243 | if (input.attr("rows") != rows)
244 | input.attr("rows", rows);
245 | }
246 | }
247 |
248 | var default_scope = {
249 | "log": log,
250 | "history": history,
251 | alert: function(msg) { alert(msg); }
252 | }
253 | disable_functions(default_scope, "window,document,t1");
254 |
255 | function disable_functions(obj, list) {
256 | var list = list.split(",");
257 | for(var i in list) {
258 | obj[list[i]] = {};
259 | }
260 | }
261 |
262 | return this;
263 | };
264 |
265 | jQuery.extend(jQuery.fn, {
266 | "autoresize": function()
267 | {
268 | var thisp = this;
269 | setTimeout(do_resize, 0);
270 |
271 | function do_resize() {
272 | var s = thisp.val() || "";
273 | var rows = s.split(/\n/).length;
274 | // + 1 // prevent scrollbar flickering in Mozilla
275 | + (window.opera ? 1 : 0); // leave room for scrollbar in Opera
276 |
277 | // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.
278 | if (thisp.attr("rows") != rows)
279 | thisp.attr("rows", rows);
280 | }
281 | return this;
282 | }
283 | })
284 |
285 |
286 |
287 | jQConsole.global_scope = this;
288 | jQConsole.our_scope = {};
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | try ruby! (in your browser)
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
38 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
Please Support Try Ruby!
56 |
57 |
59 |
60 |
61 |
67 |
68 |
69 |
First, I'd like to thank the over 365,345 (three hundred sixty five thousand three hundred fourty five) people who have used Try Ruby (globally) over 508,600 (five hundred eight thousand six hundred) times in the last two years!
70 |
It has been an honor and a privlege to help restore such a fantastic resource.
71 |
Because of the fun nature of Try Ruby, it only makes sense to allow it to reach its full potential.
72 |
Specifically, Try Ruby must have lessons for the full language.
73 |
A partial list includes
74 |
75 |
Blocks, Lambdas, Closures, and Procs
76 |
Object Model (DrX with a live svg front end)
77 |
Metaprogramming
78 |
Sandboxing
79 |
Standard lib
80 |
Unit Testing & Outside in Behavior Driven Development
81 |
The Ruby VM (Garbage Collection, Tuning, etc)
82 |
Try Ruby Offline & Mobile versions.
83 |
84 |
85 |
I have gladly covered the hosting expense (currently amazon ec2 small instance, and before that a dedicated box) for the last two years.
86 | The smile people have when experiencing the beauty of Ruby has been more than worth it. :-)
87 |
However, in order allow Try Ruby's potential to flourish- muchless stay online- I am currently raising funds. I have never placed ads or sold any information collected by Try Ruby. Please donate to help this site reach its full potential.
88 |
If all goes well, I will have weekly lessons, much in the spirit of Railscasts. Obviously these would be interative lessons.
89 |
Last, I'd like to thank David Miani for helping me reassemble Try Ruby when _why disappeared*. Also, a thanks goes out to Adrian aka "Orangea" for his eairly work in finding security holes and helping with other misc issues. A deep thanks also goes out to everyone who has ever reported a bug or issue with Try Ruby.
90 |
Thank You.
91 | Respectfully,
92 | Andrew McElroy
93 |
* _why the lucky stiff was the origional creator of Try Ruby. However he vanished from the Internet over two years ago. He took his copy of Try Ruby with him. We had to completely reimplement Try Ruby.
Ruby is a programming language from Japan
115 | (available at ruby-lang.org)
116 | which is revolutionizing the web.
117 | The beauty of Ruby is found in its balance between simplicity and power.
118 |
119 |
Try out Ruby code in the prompt above. In addition
120 | to Ruby's builtin methods, the following commands are available:
121 |
122 |
help
123 | Start the 15 minute interactive tutorial. Trust me, it's very basic!
124 |
help 2
125 | Hop to chapter two.
126 |
127 |
clear
128 | Clear screen. Useful if your browser starts slowing down.
129 | Your command history will be remembered.
130 |
back
131 | Go back one screen in the tutorial.
132 |
reset
133 | Reset the interpreter if you get too deep. (or Ctrl-D!)
134 |
next
135 | Allows you to skip to the next section of a lesson.
136 |
137 |
time
138 | A stopwatch. Prints the time your session has been open.
139 |
140 |
If you happen to leave or refresh the page, your session will still be here for
141 | unless it is left inactive for ten minutes.
142 |
143 |
144 |
145 |
146 |
147 |
Trapped in double dots? A quote or something was left open. Type: reset or hit Ctrl-D.
148 |
149 |
150 |
This place was sired by why the lucky stiff.
151 | Please contact me using the email address at that link.is maintained by Andrew McElroy and David Miani. For support issues, please post a ticket or contact Sophrinix on github.
152 |
153 |
154 |
155 |
156 |
157 |
160 |
161 |
165 |
170 |
171 |
172 | Please Support Try Ruby!
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/public/javascripts/facebox.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Facebox (for jQuery)
3 | * version: 1.2 (05/05/2008)
4 | * @requires jQuery v1.2 or later
5 | *
6 | * Examples at http://famspam.com/facebox/
7 | *
8 | * Licensed under the MIT:
9 | * http://www.opensource.org/licenses/mit-license.php
10 | *
11 | * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
12 | *
13 | * Usage:
14 | *
15 | * jQuery(document).ready(function() {
16 | * jQuery('a[rel*=facebox]').facebox()
17 | * })
18 | *
19 | * Terms
20 | * Loads the #terms div in the box
21 | *
22 | * Terms
23 | * Loads the terms.html page in the box
24 | *
25 | * Terms
26 | * Loads the terms.png image in the box
27 | *
28 | *
29 | * You can also use it programmatically:
30 | *
31 | * jQuery.facebox('some html')
32 | * jQuery.facebox('some html', 'my-groovy-style')
33 | *
34 | * The above will open a facebox with "some html" as the content.
35 | *
36 | * jQuery.facebox(function($) {
37 | * $.get('blah.html', function(data) { $.facebox(data) })
38 | * })
39 | *
40 | * The above will show a loading screen before the passed function is called,
41 | * allowing for a better ajaxy experience.
42 | *
43 | * The facebox function can also display an ajax page, an image, or the contents of a div:
44 | *
45 | * jQuery.facebox({ ajax: 'remote.html' })
46 | * jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
47 | * jQuery.facebox({ image: 'stairs.jpg' })
48 | * jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
49 | * jQuery.facebox({ div: '#box' })
50 | * jQuery.facebox({ div: '#box' }, 'my-groovy-style')
51 | *
52 | * Want to close the facebox? Trigger the 'close.facebox' document event:
53 | *
54 | * jQuery(document).trigger('close.facebox')
55 | *
56 | * Facebox also has a bunch of other hooks:
57 | *
58 | * loading.facebox
59 | * beforeReveal.facebox
60 | * reveal.facebox (aliased as 'afterReveal.facebox')
61 | * init.facebox
62 | * afterClose.facebox
63 | *
64 | * Simply bind a function to any of these hooks:
65 | *
66 | * $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
67 | *
68 | */
69 | (function($) {
70 | $.facebox = function(data, klass) {
71 | $.facebox.loading()
72 |
73 | if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
74 | else if (data.image) fillFaceboxFromImage(data.image, klass)
75 | else if (data.div) fillFaceboxFromHref(data.div, klass)
76 | else if ($.isFunction(data)) data.call($)
77 | else $.facebox.reveal(data, klass)
78 | }
79 |
80 | /*
81 | * Public, $.facebox methods
82 | */
83 |
84 | $.extend($.facebox, {
85 | settings: {
86 | opacity : 0.2,
87 | overlay : true,
88 | loadingImage : '/facebox/loading.gif',
89 | closeImage : '/facebox/closelabel.png',
90 | imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],
91 | faceboxHtml : '\
92 |