It is "module_eval", which is not the same eval as Scheme, Javascript or Clojure. It means to evaluate the code in the context of a given module, allowing you to dynamically define new methods. The old regular eval is also available.
Man, who down votes someone for asking a genuine question?
This isn't monkey patching. Ruby's classes are open (they can be modified on the fly), so you can monkey patch modules with new functionality. In a language like C, if you wanted to extend a library, you might modify it and recompile.
Ruby's module_eval and class_eval are meta-programming tools that let you programmatically add methods to classes (and lots of other stuff), this can be combined with monkey patching, if you so desire.
No, no. Monkey patching is what you can do when you have open classes. For instance, in Ruby, I can reopen the Array class and add new behavior or change existent methods. This is obviously bad idea if you are changing native behavior, but it is also what allows Ruby on Rails to extend the Integer class to make working with time expressions quite easy, as allowing the following expression: "3.days.ago".
I still haven't decided if Elixir will have open class or if I will add refinements or classboxes.
On other hand, module_eval is what allows frameworks like Rails to dynamically add code to a class, so you can do stuff like:
class Post
has_many :comments
end
And it will define a comments method and others, that allows you to easily manipulate the Post-Comment association.
This definitely makes Erlang more approachable for me - I've managed to develop a strong dislike for the syntaxes in a lot of functional languages including Lisp and Haskell. From my perspective, the syntactic choices documented in https://github.com/josevalim/elixir seem rather reasonable on the whole, but functions are a tad odd. Is there any specific reason why it's "-> (x, y) x + y"? I always thought the motive for the arrow notation in the form "(x, y) -> x + y" was an obvious cognitive mapping into "x and y becomes x + y". Seems a bit bass ackwards as it is. I also have a minor issue with the atom prefix (to me : would have been more distinctive), but that's admittedly more of a personal thing.
I'm glad that you found the syntax reasonable as a whole. :D Regarding to functions and atoms, their syntax choices are a trade-off. If I have "(x, y) -> x + y" for functions, I need explicit parens when invoking a method (otherwise we will have ambiguity), so I prefer to have this flexibility on method invocations. A similar choice happened to atoms. As I preferred to save ":" for dicts, as in { x: y }, the syntax would get very confusing if I allowed: { :x: :y }. That said, I have chosen 'atom, which is common in some Lisp dialects.
Having now read the entirety of the readme, I'm left a bit unclear on the object model's semantics. If I declare a mixin in an object, those become class methods? Whereas declaring a prototype results in instance methods? Also, "set_ivar" seems like a needlessly complex and obscure statement.
There is one key difference right now: Elixir is much better documented. Elixir also has a well defined Object Model which helps a lot understanding what is going on and makes meta programming easier. I also find Elixir data structure's syntax closer to Erlang's, but that is not necessarily something positive or negative.
11 comments
[ 3.5 ms ] story [ 37.6 ms ] threadThis isn't monkey patching. Ruby's classes are open (they can be modified on the fly), so you can monkey patch modules with new functionality. In a language like C, if you wanted to extend a library, you might modify it and recompile.
Ruby's module_eval and class_eval are meta-programming tools that let you programmatically add methods to classes (and lots of other stuff), this can be combined with monkey patching, if you so desire.
I still haven't decided if Elixir will have open class or if I will add refinements or classboxes.
On other hand, module_eval is what allows frameworks like Rails to dynamically add code to a class, so you can do stuff like:
And it will define a comments method and others, that allows you to easily manipulate the Post-Comment association.2) Yes, adding a syntax to easily change instance variable values is one of the most asked features. The tricky part is, we cannot do the following:
Because that is pattern matching and in Erlang/Elixir, we cannot modify objects in place. The expression above needs to return a new object.I was thinking about something like @{'foo : "bar"}, but I haven't decided yet. Suggestions are welcome. :D