An idiom I like... modifiable defaults

ruby

    Next

  • 1. Thread-safe initialization in a C extension
    I'm working on a Ruby extension written in C and I would like to know what implications Ruby 1.8's "green" threading model has for the once- only initialization of file-scoped static variables. The following is my code with no explicit attempts at thread-safety. Do I need them under "green" threading? Cheers, Wincent static VALUE rb_Iconv = 0; VALUE _setup_iconv() { // no attempt at thread safety here (TODO: add it?) if (rb_Iconv == 0) { rb_require("iconv"); rb_Iconv = rb_path2class("Iconv"); if (NIL_P(rb_Iconv)) rb_raise(rb_eLoadError, "failed to load Iconv class"); else return Qtrue; } return Qfalse; }
  • 2. block params scoping (was ruby-talk 257917: Using a block to surround a string?)
    Fr David Black: # Method definitions always have their own local scope, so a, b, and # string are strictly local to the method. Blocks pick up the scope # that they're created in, and can also create variables that weren't # already in that scope. Those variables disappear when the block # exits; the ones that were there already survive: # # x = 1 # some_method { y = x + 1 } # same x; new y # y # undefined; block's y didn't survive # x # same x Hi David, How about parameter variables, will its scoping change/stay in ruby2 ? Currently, irb(main):011:0> x="testing" => "testing" irb(main):012:0> 5.times{|x|} => 5 irb(main):013:0> x => 4 i'd prefer x = "testing" some_method { |x| y = x + 1 } # different x; overrides any x x # => "testing", same x outside just asking for ruby englightenment kind regards -botp

An idiom I like... modifiable defaults

Postby Hal Fulton » Tue, 10 May 2005 23:42:44 GMT

Just thought I'd share a little concept that I find
useful. Your comments are welcome.

Sometimes objects are created with certain defaults.
One way to override them is with default values in
the constructor (and often corresponding writer methods).

But sometimes I "don't like" the default and want to
change it (for this program/session).

Often I use class-level accessors for that purpose.

Here's a contrived example...


Cheers,
Hal


   class Text

     class << self
       attr_accessor :color
       Text.color = "black"
     end

     attr_accessor :color

     def initialize(txt, color="black")
   # Hint: You can improve this further by saying
   # def initialize(txt, color=Text.color)
       puts "#{color} text..."
     end
   end


   # The old way...

   a = Text.new("some")           # black
   b = Text.new("random","blue")  # blue
   c = Text.new("text")           # black
   c.color = "blue"               # but now it's blue

   # The new way...

   Text.color = "blue"

   e = Text.new("Ruby is cool")   # blue
   f = Text.new("as dry ice")     # blue





Re: An idiom I like... modifiable defaults

Postby Robert Klemme » Wed, 11 May 2005 00:31:09 GMT



Thinking in code - some other approach:

def hash_replace(hash, replacement)
  tmp = hash.dup

  begin
    hash.update replacement
    return yield
  ensure
    hash.clear
    hash.update tmp
  end
end


=> {1=>2, :foo=>"bar"}
{1=>2, :foo=>"bar"}
=> nil
?>   p Test::DEFAULTS
{1=>2, :foo=>"replaced"}
=> nil
{1=>2, :foo=>"bar"}
=> nil

Hm...

Kind regards

    robert



Re: An idiom I like... modifiable defaults

Postby Ilmari Heikkinen » Wed, 11 May 2005 00:43:40 GMT





Hi,
I quite like this, but wonder if it works with inheritance?

On a related note, it seems a lot of people (you, me, Ara Howard, 
probably many others) are coming up with these configuration idioms, 
maybe we could find a way that fulfills most needs (and perhaps even 
try to get it into ruby core)?

Here's a quick list of features for discussion, feel free to add your 
own:
- named arguments (ie. hash argument way)
- auto-assigning configuration vars to instance variables
- works with inheritance (this is probably the most difficult -- and 
useful -- one)
- auto-generated accessors
- configuration by block
- maybe some way to co-operate with the regular positional params


Would look something like this in use:

class Image
   include TheAutoConfigModule
   config_accessor{
     name # defaults to nil
     width = 100
     height = 100
     depth = 32
   }
   def bytes
     @width * @height * @depth / 8
   end
end

class BWImage < Image
   config_accessor{ depth = 8 }
end

i = Image.new(:height => 200, :depth => 16)
i.width == 100 and i.height == 200 and i.depth == 16
#=> true
i.name
#=> nil
i.bytes
#=> 40000

bwi = BWImage.new( 'holiday shots', 10, 10 )
bwi.width == 10 and bwi.height == 10 and bwi.depth == 8
#=> true
bwi.name
#=> 'holiday shots'
bwi.bytes
#=> 100

Image.config
#=> {:name => nil, :width => 100, :height => 100, :depth => 32}

BWImage.config.height = 200
BWImage.config
#=> {:name => nil, :width => 100, :height => 200, :depth => 8}

Thoughts?


Cheers,
Ilmari





Re: An idiom I like... modifiable defaults

Postby Ara.T.Howard » Wed, 11 May 2005 02:29:15 GMT




i do this so much i built it in to my new traits lib (currently being
updated).  works like:

   harp:~ > cat a.rb
   require 'traits'

   class Text
     class_trait 'color' => 'black'
     trait 'color'

     def initialize opts = {}
       color( opts['color'] || opts[:color] || Text.color)
     end
   end

   Text::color = 'blue'
   p Text::new


   harp:~ > ruby a.rb
   #<Text:0xb75bb744 @color="blue">

i generally also allow modifing classes via the environment, eg:

   class Text
     class_trait 'color' => (ENV['TEXT_COLOR'] || 'black')
     trait 'color'
     def initialize opts = {}
       color( opts['color'] || opts[:color] || Text.color)
     end
   end

i'm using this in all cases except true constants - like PI.

cheers.


-a
-- 
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================


Re: An idiom I like... modifiable defaults

Postby Berger, Daniel » Wed, 11 May 2005 03:24:42 GMT

> -----Original Message-----

<snip>


I smell an "Advanced Ruby Programming" book in the works. ;)

Dan




Re: An idiom I like... modifiable defaults

Postby Glenn Parker » Wed, 11 May 2005 03:32:43 GMT



Not very thread-safe, at least not in your example's implementation.

-- 
Glenn Parker | glenn.parker-AT-comcast.net | < http://www.**--****.com/ ;



Re: An idiom I like... modifiable defaults

Postby Brian Buckley » Wed, 11 May 2005 04:36:20 GMT



Does anyone know of any Advanced or Intermediate or even good Beginning Ruby 
programming books in the works? 

I've only got PickAxe2. The handful of other Ruby books are all at least 4 
years old. Any comments on how current those still are?

Brian


Re: An idiom I like... modifiable defaults

Postby Ara.T.Howard » Wed, 11 May 2005 05:08:25 GMT






even this is not:

   class C
     attr_accessor :x
   end

unless you make it.

FYI.

-a
-- 
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================


Re: An idiom I like... modifiable defaults

Postby Glenn Parker » Wed, 11 May 2005 06:39:13 GMT





Yes, if instances of class C are to be accessed from multiple threads, 
then some extra care is needed, but that depends very much on the actual 
uses of the class.  A lot of classes never need to worry about it, even 
in highly threaded applications.

In the OP's code, it's clear that all threads using class Text will be 
in contention for Text.color.  In that style of interface, a per-thread 
variable is practically mandatory.

-- 
Glenn Parker | glenn.parker-AT-comcast.net | < http://www.**--****.com/ ;



Re: An idiom I like... modifiable defaults

Postby Hal Fulton » Wed, 11 May 2005 07:56:11 GMT





No. I suppose if I were using this with threads I would
wrap the thread-safety code around it rather than hiding
it inside.


Hal





Re: An idiom I like... modifiable defaults

Postby Martin DeMello » Wed, 11 May 2005 13:50:00 GMT



This is actually my primary use case for class variables (@@var) -
inheriting configuration defaults down a class tree.

martin

Re: An idiom I like... modifiable defaults

Postby Ilmari Heikkinen » Wed, 11 May 2005 14:27:05 GMT







The problem with class vars is that changing them in the subclass 
affects the superclass aswell.

class A
   @@foo = "A"
   def foo; @@foo; end
end

class B < A
   @@foo = "B"
end

A.new.foo
=> "B"




Re: An idiom I like... modifiable defaults

Postby Martin DeMello » Wed, 11 May 2005 14:40:50 GMT





Yes, but you're the programmer - simply don't change them in the
subclass.

martin

Similar Threads:

1.basic question: passing a modifiable argument to a routi

2.basic question: passing a modifiable argument to a routine

Arguments to subroutines seem to be passed by value in ruby

$ irb
irb(main):001:0> def woof(a)
irb(main):002:1>   a += 2
irb(main):003:1> end
=> nil
irb(main):004:0> b = 5
=> 5
irb(main):005:0> woof(b)
=> 7
irb(main):006:0> b
=> 5
irb(main):007:0>

so how do I pass a variable to a routine if I want the routine to
modify the variable.  In C I would say:

void woof(int *a) {
    *a += 2;
}
int b = 5;
woof(&b);
printf("%d\n", b);

would output 7.

3.Eddie Huntington Cvrcko likes hurricanes

Eddie Huntington Cvrcko

HOUSTON - Hurricane Ike, a colossal storm nearly as big as Texas
itself, began battering the coast Friday, threatening to obliterate
waterfront towns and give the skyscrapers, refineries and docks of the
nation's fourth-largest city their worst pounding in a generation.
ADVERTISEMENT

As the storm closed in, it trapped 60 people who had to be rescued
from the floodwaters by helicopter, sent towering waves smashing over
the 17-foot Galveston seawall, breached levees in rural Louisiana, and
tossed around a disabled 584-foot cargo ship in the Gulf of Mexico.

About a million people in low-lying coastal areas were ordered to get
out well ahead of the storm. But authorities in three counties alone
said roughly 90,000 of them refused, despite a warning from
forecasters that those staying behind in Galveston faced "certain
death."

"I believe in the man up there, God," said William Steally, a 75-year-
old retiree who planned to ride out the storm in Galveston without his
wife or sister-in-law. "I believe he will take care of me."

At about 600 miles across, the hurricane was one of the largest in
recent memory, taking up almost the entire northern half of the Gulf
of Mexico.

As of 5 p.m. EDT, Ike was centered about 135 miles southeast of
Galveston, moving at 12 mph. It was a Category 2 storm, with winds of
105 mph, but was expected to strengthen to a Category 3, or at least
111 mph, by the time it hit land.

Forecasters predicted it would come ashore somewhere near Galveston
late Friday or early Saturday and pass almost directly over Houston.

Because of the hurricane's size, the state's shallow coastal waters
and its largely unprotected coastline, forecasters said the biggest
threat would be flooding and storm surge, with Ike expected to hurl a
wall of water two stories high 20 to 25 feet at the coastline.

To avoid highway gridlock, authorities instructed most of Houston's 2
million residents to just hunker down.

Still, authorities warned that the storm could travel up Galveston Bay
and send a surge up the Houston Ship Channel and into the port of
Houston, the nation's second-busiest port a complex of docks,
pipelines, depots and warehouses that receives automobiles, consumer
products, industrial equipment and other cargo from around the world
and ships out vast amounts of petrochemicals and agricultural
products.

The oil and gas industry was also closely watching Ike because it was
headed straight for the nation's biggest complex of refineries and
petrochemical plants. Wholesale gasoline prices jumped to around $4.85
a gallon for fear of shortages.

The storm could also force water up the seven bayous that thread
through Houston, swamping neighborhoods so flood-prone that they get
inundated during ordinary rainstorms.

Bachir Annane, a scientist at the National Oceanic and Atmospheric
Administration's Hurricane Research Division, said Ike's surge could
be catastrophic, and like nothing the Texas coast has ever seen.

"Wind doesn't tell the whole story," Annane said. "It's the size that
tells the story, and this is a giant."

Ike would be the first major hurricane to hit a U.S. metropolitan area
since Katrina devastated New Orleans three years ago. For Houston, it
would be the first major hurricane since Alicia in August 1983 came
ashore on Galveston Island, killing 21 people and causing $2 billion
in damage.

In southwestern Louisiana near Houma, Ike breached levees, threatening
thousands of homes of fishermen, oil-field workers, farmers and
others. Crews struggled to plug four breaches. "We've got a bad
situation," said Windell Curole, levee manager for Terrebonne Parish.

Before the storm even arrived, rescue crews were being tapped. Because
of high winds, the Air Force and Coast Guard aborted plans to send
aircraft to the Gulf of Mexico in a daring attempt to rescue 22
crewmen adrift on a stalled freighter in rough seas 90 miles off
Galveston.

And Coast Guard helicopter crews plucked 60 people from the town of
High Island on the Bolivar Peninsula, a 32-mile spit just up the coast
from Galveston, after rising waters covered the only road.

In Galveston, a working-class town of about 57,000, waves crashed over
the 11-mile seawall built a century ago, after the Great Storm of 1900
killed 6,000 residents. That hurricane remains the nation's deadliest
natural disaster.

The sight of the storm's fury frightened some people who initially
intended to stay.

"We started seeing water come up on the streets, then we saw this. We
just loaded up everything, got the pets. We're leaving," 33-year-old
Tony Munoz said in Galveston. "I've been through storms before, but
this is different."

While the beachfront is dotted with new condominiums and some elegant
beach homes on stilts, most people live in older, one-story bungalows.
The National Weather Service warned "widespread and devastating"
damage was expected.

In Surfside Beach, a town of 800, the police chief asked one stubborn
couple, David and Dondi Fields, to write their names and Social
Security numbers on their forearms with a black marker in case
something bad happened to them.

Dondi Fields, 50, wrote "I heart U" and "for my kids" on her arm. But
the couple finally decided to leave. Police used an aluminum boat to
reach them, and a National Guard truck carried them to safety.

In Freeport, Drew Ryder, 47, took no chances. He left his plywood-
covered home, heading north with coolers filled with food.

"It's coming, so I'm going," he said. "It's not smart to be here."

Houston's streets were eerily quiet, emptied of the usual weekday
traffic. Skyscrapers were darkened, and sandbags protected the lobby
doors to some.

At the Flying Saucer Draught Emporium, a bartender secured plywood
over windows as two dozen customers drank beer, ate burgers and
watched scenes of Galveston on giant TV screens.

Andy Weeks, a retiree who serves as the homeowners association
president in the eight-story building, spent the morning knocking on
doors and reminding neighbors to bring their patio furniture and
plants inside. The windows were bare of any plywood or other
protection.

"It's pretty tough to get outside to board up your windows," said 64-
year-old Weeks, who lives on the sixth floor.

Gloria Dulworth, who lives on the seventh of a high-rise apartment
building, refused to let the storm dampen her plans to celebrate her
81st birthday.

"We're surrounded by glass, so I'm taking my crystal candlesticks
down. It's been suggested that we roll the rugs away from the door,"
in case water seeps in. Other than that, said Dulworth, "I'm going to
get some fresh veggies. I have cereal and canned milk. I anticipate
being without air conditioning for a couple of weeks, but you can't do
much."

4.The likes of AOP (1 of 2)

I've been doing some thinking on AOP ...

There are three fundematnal implementations types of AOP: Static Weaving, 
Dynamic Weaving and Dynamic Triggering (Event-based). 

So how do these differ?

Static weaving simply looks at source and based on it determines where to add 
(and possibly remove) code.[1] Thus it is limited to the program definition 
and cannot alter the program based on any execution state. This works okay 
for static languages like C, but would never do for a dynamic language like 
Ruby simply b/c the code itself can change on the fly. That's where Dynamic 
Weaving comes in. It is the same as Static Weaving except that it can react 
to dynamic code changes; it is thus an AOP necessity for any dynamic language 
like Ruby. But that is really all it is --it simply adjusts for weaves based 
on code changes, NOT state changes. While it is possible for Dynamic Weaving 
to dynamically add and (potentially remove) weaves based on state changes, 
doing so is exceedingly hackish --it is much easier to check for state 
changes within permanently weaved advice. To properly aspect code based on 
state one must move to full-fledged Dynamic Event-based Triggering AOP.

In my experimentation with "legacy" AOP implementations like that of AspectJ 
and AspectR, I've come to the conclusion that they are of only minor use in a 
language as dynamic as Ruby. With a good mechanism for weaving, like `class 
cuts`, reentrant classes, and a good set of callbacks, one can do everything 
AspectJ, or like lib, can do in a way generally more fitting the actual 
problem. Consider:

  class AnAspect < Aspect
    def pointcut( jp )
      :advice if jp.klass.name =~ /^T/ && jp.meth.to_s =~ /^t/
    end
    def advice(*args)
      puts "Log #{target.meth} args.inspect" 
    end
  end

vs. 

  class Class
    def method_added( meth )
      if self.name =~ /^T/ && meth.to_s =~ /^t/
        Cut.new( self ).send(:define_method, meth) do |*args|
          puts "Log #{meth} args.inspect"
        end
      end
    end
  end

The former "traditional" AspectJ-esque way is a bit easier to read, which is 
nice, but only a bit. Any implementation of an AspectJ-like lib for Ruby will 
essentially translate the former into something akin to the later (albiet a 
more efficient implementation [2])

So it does not strike me as largely significant to design yet another YAAR 
(Yet Another Aspect lib for Ruby) --on the whole the matter is fairly 
straight forward.

I need to take a break. I will be following this up with some more thoughts on 
Event-based AOP.

T.


== FOOTNOTES ==

1  An interesting thought is whether it could weave code based on its own 
previous weaves --and thus the potential for an infinite aspecting. Ouch.

2  Peter you might notice why I used the #clearcut method in dynaop.rb from 
the above example. With it I was able to advise methods individually while 
minimizing the number of Cuts added to a class (fro efficiency). This makes 
me think that an excellent support method for cuts would be exactly that:

  Class.define_cut_method( sym ) { |*args| ... }

This would define a method in the nearest cut of class lacking the method 
#sym, or create a new cut for if need be. Then the above implmentation 
becomes simply:

  class Class
    def method_added( meth )
      if self.name =~ /^T/ && meth.to_s =~ /^t/
        self.define_cut_method( meth ) do |*args|
          puts "Log #{meth} args.inspect"
        end
      end
    end
  end

And perhaps a better name for that method is simply #wrap ;)



5.Who likes Sudoku?

6. McGovern Likes JRuby...

7. inject idiom

8. Ruby idiom for all matches in a string



Return to ruby

 

Who is online

Users browsing this forum: No registered users and 31 guest