-
-
Notifications
You must be signed in to change notification settings - Fork 329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interact/access javascript objects/methods #14
Comments
Hi, can you please give some samples about using jquery or dom (like document.querySelectorAll), how to pass parameters to js commands ? it's very interesting to be able coding with ruby in navigator, thanks for this sorry about my english (i'm french) |
Well, using your given example Im currently trying to solve two issues: accessing 'global' js objects/variables (e.g. Accessing global js objectsThe opal compiler has no way to know about global objects at compile time, i.e. it cannot look through your code and determine that One solution I'm looking at is to override the use of global variables to compile down to basic javascript variable names. For example, the following ruby code: foo = $document; Would compile into something like: var foo = document; The opal compiler will determine that global var access is just accessing global javascript variables. Obviously special ruby globals ( If we wanted to be clever, we could compile these globals to check for a variable existence first and return var foo = (typeof document != undefined ? document : nil); This is the best way I can see for easy access to js variables while keeping (mostly) ruby semantics. Calling native functionsOnce we have a reference to these global variables, accessing their functions is the tricky part. A feature (or pain) of js is that you can access functions, or other properties, of an object by omitting call parens (unlike ruby which calls a method anyway). To keep things in opal fast, strings, numbers and arrays point to their native javascript equivalents. This has a side effect that every ruby array, string and number have these js properties already attached. The opal compiler therefore appends This also means that accessing a function, like The alternativeThe alternative to these two 'solutions' is to make use of the current back tick syntax that can hold raw javascript, and is just output as given. For example, to use your given method, you could do: elements = `document.querySelectorAll('div')`
# pass elements somewhere else
do_something_with_elements elements
# raises an error as elements does not have any ruby methods..
elements.try_some_method() As nice as being able to directly call js methods would be, loosing specific ruby features that make ruby great would remove the benefit of being able to use ruby in the browser. I hope this clears up the current method of accessing js objects and what might make it into opal next. |
wahooo! thanks a lot, i'm going to play with it |
OK, i've understood
|
Nice project, is it supposed to be compatible with Node.js? About access to JS, maybe it's possible to use something like this? [1, 2, 3, 4].native.length
[1, 2, 3, 4].js.length |
It does work with node.js, but not in the master branch. I will be pushing node.js support in a day or so once I tidy up the file system methods. I do like the approach using opal.document # => document
opal.window # => window I'll keep you updated here on the node.js updates. |
Why not using Ruby's global syntax to access globals?
Didn't give a look at the |
Yeah, the global syntax seems the better way. I think it should be used just for accessing globals - not writing, i.e. when setting a ruby global it shouldnt really set a global in js. As for the property access, well, compile time detection wouldnt be all that easy. The compiler will not have access to some prototypes to check, for instance it won't know which jquery properties are simple properties, like class JQuery
native_proptery :length, :selector
native_function :next, :prev
end ... or something similar. |
Agree with the global setter being Ruby only. I'd sincerely go with the |
Im not sure I follow.. how would the compiler determine that a method call on a object is trying to access native properties/functions compared to a normal ruby method call? The dynamism of ruby means theres no guaranteed way to know the type of the receiver and therefore what its native properties are. |
Well, you coul keep a native thing table somewhere, but yeah, you're probably right, easier to go with |
Currently Opal needs to wrap any native js construct (arrays, jquery instances, custom libraries etc) so they can be accessed in a ruby way - i.e. so we still get method_missing, "getter" and "setter" methods, operator overloading etc. Opal still needs a proper way to interact with js objects without using the backtik approach.
One solution is to use the
::
construct to access javascript properties. For instance, to get an array length using its native length property, we could use:Instead of the method call version:
Another approach is to make it obvious that we are running directly on top of javascript, and maybe make an "opalscript" branch which is more of a ruby syntax for javascript, rather than a ruby runtime on top of javascript. Method calls would follow perhaps Coffeescript's style where a call without args and parans is simply a property access.
The text was updated successfully, but these errors were encountered: