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

···

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

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

Farrel

···

On 17/08/06, Henry Savr <hsavr@yahoo.com> wrote:

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

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

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 Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
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.

···

On Thu, 17 Aug 2006, Henry Savr 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

Farrel Lifson wrote:

···

On 17/08/06, Henry Savr <hsavr@yahoo.com> 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

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

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

···

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

Henry Savr wrote:

Farrel Lifson 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
  

The good question is: what for ? In the case of the accessors, the
methods are define when the class is evaluated ... but when it is used,
there is no difference between accessors defined that way and accessors
defined the Hard Way (tm). The Good Thing (tm) with a dynamic language
as Ruby is you can safely generate your code (or parametrize it) so as
to avoid lot of typing, without any need for another macro-language, so
why not using this capability ?

Pierre

···

On 17/08/06, Henry Savr <hsavr@yahoo.com> wrote:

There is no preprocessor for Ruby.

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

-austin

···

On 8/17/06, Henry Savr <hsavr@yahoo.com> wrote:

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

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * http://www.halostatue.ca/feed/
               * austin@zieglers.ca

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 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

----------------------------------------------------------------

Matthew Johnson 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.

···

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

Matthew Johnson 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 Lifson, 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...

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

Matthew Johnson 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 Lifson, 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.

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.

···

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

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

Henry Savr <hsavr@yahoo.com> writes:

<a desire for macros in ruby>

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.

···

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.map{|i|i}[1] )
       puts "s=%q(#{s})",s.map{|i|i}[1]

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

···

On 8/28/06, Logan Capaldo <logancapaldo@gmail.com> wrote:

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

> Matthew Johnson 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 Lifson, 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.
>
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.

> > 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.

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

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:

···

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

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