Need - macros feature

Dear Ruby gurus:

Are there Ruby macro features as a part of Ruby standard?
I want them to work with ANY editor or interactive environment and with
ANY OS

Why?

Because it is distracting to key-in:

def a1
@a1
end
def a1=(value)
@a1=value
end

when you are thinking just about class’ very general behaviour.
I would prefer to key-in something like this initially:

%def a1

and POSSIBLY add: -r, or -w, or -rw
on early design stage. Entering all the juzz above distracts strongly.
I’m going to work on details later.

Besides, I work on various systems and I want to have unified macro
options just by installing Ruby.

Thank you,
Henry

On 17/08/06, Henry S. [email protected] wrote:

def a1


Posted via http://www.ruby-forum.com/.

attr_accessor :a1 # RW
attr_reader :a1 # R
attr_writer :a1 # W

Farrel

Farrel L. wrote:

On 17/08/06, Henry S. [email protected] wrote:

def a1


Posted via http://www.ruby-forum.com/.

attr_accessor :a1 # RW
attr_reader :a1 # R
attr_writer :a1 # W

Farrel
Thank you,
but my question was about MACRO option, so the preprocessor should work
and produce ruby source

On 8/17/06, Henry S. [email protected] wrote:

Thank you,
but my question was about MACRO option, so the preprocessor should work
and produce ruby source

There is no preprocessor for Ruby.

Farrel’s suggestion (metaprogramming with attr_accessor) is the right
one.

-austin

There is no preprocessor for Ruby.

Farrel’s suggestion (metaprogramming with attr_accessor) is
the right one.

Yep, you’re right. But he wants to know how to do it himself.
He wants to understand Why [1]… ;]

gegroet,
Erik V. - http://www.erikveen.dds.nl/

[1] http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

PS: Beer, downtown Amsterdam, tonight. No pancakes.


Abstraction through meta-programming

Getters and Setters - A Demo

Consider this code:

class Foo
def bar
@bar
end

def bar=(new_bar)
@bar = new_bar
end
end

This can be rewritten to this:

class Foo
def self.getter(iv)
define_method(“#{iv}”) do
instance_variable_get(“@#{iv}”)
end
end

def self.setter(iv)
define_method(“#{iv}=”) do |new_value|
instance_variable_set(“@#{iv}”, new_value)
end
end

getter :bar
setter :bar
end

Which can be rewritten to this:

class Module
def getter(iv)
define_method(“#{iv}”) do
instance_variable_get(“@#{iv}”)
end
end

def setter(iv)
define_method(“#{iv}=”) do |new_value|
instance_variable_set(“@#{iv}”, new_value)
end
end
end

class Foo
getter :bar
setter :bar
end

Which can be rewritten to this:

require “getter_and_setter.rb” # Fill it your self… ;]

class Foo
getter :bar
setter :bar
end

Use it:

foo = Foo.new
foo.bar = “Hello World!”
puts foo.bar

Thank you, guys
Although it’s not what I wanted, I have a lot of ideas in some
directions. It’s good for new in Ruby.
Henry

On Thu, 17 Aug 2006, Henry S. wrote:

Are there Ruby macro features as a part of Ruby standard?
I want them to work with ANY editor or interactive environment and with
ANY OS

Ruby is it’s own macro preprocessor and it is way way way smarter and
better than any other you have met. (Unless you have met Scheme hygienic
macros)

Say
ri eval
and
ri class_eval
and
ri instance_eval

The evils of eval can easily exceed the (relatively) minor sins of a
preprocessor and will eventually eat you.

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [email protected]
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.

Matthew J.son wrote:

Thank you, guys
Although it’s not what I wanted, I have a lot of ideas in some
directions. It’s good for new in Ruby.
Henry

Can you describe some of your ideas? That would certainly help
foster discussion…

Matthew

Sure I will, but I am very short in time now. That was why I could not
be here earlier. Next week is for sure.

Thank you, guys
Although it’s not what I wanted, I have a lot of ideas in some
directions. It’s good for new in Ruby.
Henry

Can you describe some of your ideas? That would certainly help
foster discussion…

Matthew

On Aug 28, 2006, at 1:11 PM, Henry S. wrote:

You wrote the macro once and put it in macro library
======== end of macro %var definition =============================

Ruby style allows to expect, that it may be done on-fly.
post convinced me to learn more about attributes on this very
beginning
stage, and that was very usefull). I want the macro power options
themselves.

I think maybe you underestimate what can be done with meta
programming in ruby that (almost) obviates the need for macros.

class Module

“macro” definition

def var(symbol)
define_method("#{symbol}=") { |value| instance_variable_set("@#
{symbol}", value) }
end
end

class A
var :my_lovely_var
end
a = A.new
a.my_lovely_var = 1

Maybe if you can come up with a less trivial example, you can stump
us, but I doubt it.

Matthew J.son wrote:

Thank you, guys
Although it’s not what I wanted, I have a lot of ideas in some
directions. It’s good for new in Ruby.
Henry

Can you describe some of your ideas? That would certainly help
foster discussion…

Matthew

There is nothiing new. It’s as old as Univac
What I want is a classic Macroprocessor tool.
I mean:
I keep pieces of souce code in some place.
They may be included in source code as is. More interesting, you can
adjust macroprocessor’s output (hence, the input for Ruby interpeter)
using paremters.

E X A M P L E:

You wrote the macro once and put it in macro library
(here I “invented” the “macrolanguage” on-fly, while writing the
example. I hope, the “language” is clear)

====this is a macro %var with argument %%x definition==============
macro: %var (%%x)

{def %%x=(value)
@%%x = value
return @%%x
end}
======== end of macro %var definition =============================
You may consider the macro definition as a template.

Now, somewhere in your code you write:

%var(my_lovely_var)

Once found the %var, macroprocessor should make substitutions and
produce this piece:

def my_lovely_var=(value)
@my_lovely_var = value
return @my_lovely_var
end

which will be inserted into code on the place, where the statement
%var(my_lovely_var) was instead of it.

Ruby style allows to expect, that it may be done on-fly.

So, finally the Ruby interpreter will execute the macroprocessor’s
output, not input. Besides the macroprocessor’s input and output are
saved, so you can return to them and change the simple lines of
get/set-code to something more complicated and valueable.

Again the get/set operations are just an EXAMPLE, used because everyone
is familiar with this piece of code. Sure, using attributes is kind of
solution for this particular case. (BTW. Thank you, Farrel L., you
post convinced me to learn more about attributes on this very beginning
stage, and that was very usefull). I want the macro power options
themselves.

Sure, every language may consider any code as an input string, and
process the string, (and Ruby itself is a great for these purposes), but
macroprocessor is something very specialized for swiftness and
convinience, to do particular job of entering the code. Ruby’s
macroprocessor tool may be specialized for entering Ruby code, which
would make it more powerful.

There are plenty of editors with comprehensive macro functions. But they
are OS dependent. As Ruby is claimed to be system independent, I would
prefer to have Ruby’s own macroprocessor, built for Ruby in mind.

More I am writing on this topic, more I am thinking, that a highly
customized for Ruby editor with macro functions would be the solution…

On 8/28/06, Logan C. [email protected] wrote:

foster discussion…

  @%%x = value

everyone
class Module
a = A.new
a.my_lovely_var = 1

Maybe if you can come up with a less trivial example, you can stump
us, but I doubt it.

While Ruby’s metaprogramming facilities are indeed powerful, they
still don’t allow you to change the syntax of the language as Lisp
macros allow. So, for example, if I wanted to define a new operator
:= for assignment semantics I can’t do that with metaprogramming, but
if Ruby had Lisp-like macros it would be possible.

Phil

  @%%x = value

Once found the %var, macroprocessor should make substitutions and
produce this piece:

def my_lovely_var=(value)
@my_lovely_var = value
return @my_lovely_var
end

which will be inserted into code on the place, where the statement
%var(my_lovely_var) was instead of it.

Here is one way:

var = lambda { |x| %q{
def #{x}=(value)
#{x} = value
return #{x}
end
}}

eval(var[“my_lovely_var”])

You can easily define and use multiple levels of macros. This is
kind-of
the way I do it in my parser generation to make a relatively flat
parser. I
add the ability to use objects inside the macro so that they have the
same
flexibility as closures. You have to explicitly pass the objects you
want
to use, though.

Eric

On Aug 28, 2006, at 2:53 PM, Phil T. wrote:

Phil

Yes I know, which is why I said (almost). OTOH Lisp macros letting
you change the syntax is sort of a red herring, since all lisp syntax
looks the same anyway :wink:

Henry S. [email protected] writes:

What about this? It’s still a far cry from lisp macros, as it only
lets you define macros that work at the module level, and you need to
appropriately quote the input to a macro yourself, but I think with a
bit more reworking we could get “macros” to work at whatever level was
desired.

class Module
def defmacro(symbol, &block)
methodproc = Proc.new {|*a|self.class_eval(block.call(*a))}
self.send(:define_method, symbol, methodproc)
end

Example macro that does what was mentioned in the long request:

defmacro(:var){|name,init|%Q{
def #{name}
@#{name} = #{init.inspect} unless defined? @#{name}
@#{name}
end
def #{name}=(val)
@#{name}=val
end
}}

A silly macro - creates some number of attributes all

with the same prefix, and initial values nil

defmacro(:varfamily){|name,n|
(1…n).map{|i|“var :#{name}_#{i}”}.join(“\n”)
}
end

Now let’s test this out:

irb(main):033:0> class Foo; varfamily :foo,10; end
=> nil
irb(main):034:0> g = Foo.new
=> #Foo:0x299b668
irb(main):036:0> g.methods.select{|m|m=~/^foo/}.sort
=> [“foo_1”, “foo_10”, “foo_10=”, “foo_1=”, “foo_2”, “foo_2=”,
“foo_3”, “foo_3=”, “foo_4”, “foo_4=”, “foo_5”, “foo_5=”,
“foo_6”, “foo_6=”, “foo_7”,“foo_7=”, “foo_8”, “foo_8=”,
“foo_9”, “foo_9=”]
irb(main):037:0> g.foo_5
=> nil
irb(main):038:0> g.foo_5=6
=> 6
irb(main):039:0> g.foo_5
=> 6

I still think that you’re almost always better off using some already
present meta-programming tool, but if you really want a string-parsing
macro soup, this might do the trick.