# -*- merd -*- # The examples are taken from the Perl Cookbook # By Tom Christiansen & Nathan Torkington # see http://www.oreilly.com/catalog/cookbook for more #@@PLEAC@@_NAME Merd #@@PLEAC@@_WEB http://merd.sf.net/ #@@PLEAC@@_1.1 s = "This is what you have" first = s[0] # "T" start = s[5..7] # "is" rest = s[13..] # "you have" last = s.last # "e" end = s.lasts(4) # "have" piece = s.lasts(8 .. 5) # "you" # magic substr not usefull (?) s.subst!(G, "is", "at") #@@PLEAC@@_1.2 2 &&& "ee" # -> "ee" 0 &&& "ee" # -> "" "a" ||| "b" # -> "a" "" ||| "b" # -> "b" x |||= "b" #@@PLEAC@@_1.3 (a, b) = (b, a) #@@PLEAC@@_1.4 # Char::ord !! int # Int::chr !! char "HAL".map(next) # "IBM" #@@PLEAC@@_1.5 # a string is a list, no pb println( "unique chars are: {"an apple a day".uniq.sort}") println(qq(unique chars are: {"an apple a day".uniq.sort})) #@@PLEAC@@_1.6 println(s.rev) # reverse letters println(s.words.rev.join(" ")) # reverse words long_palindromes = cat("/usr/dict/words").map(chomp).filter(s -> s == s.rev && s.size > 4) #@@PLEAC@@_1.7 s.expand_tabs = s.fixpoint( break(, "\t", a,b -> a + " ".times(8 - a.size modulo 8) + b ) ) #@@PLEAC@@_1.8 # forbidden, use one of: s = "You owe {debt} to me" fs(s) = "You owe {s} to me" fs':= sprintf("You owe %s to me",) "I am 17 years old".subst(G, "(\d+)", (n -> "{2 * n}")) "I am 17 years old".subst(G, "(\d+)", *2 ~ to_string) #@@PLEAC@@_1.9 e = "bo peep".upcase e.downcase! e.capitalize! "thIS is a loNG liNE".words.map(capitalize) #@@PLEAC@@_1.10 println("I have {n + 1} guanacos.") w = "work" very := () -> "very" well() = "well" "this is gonna {w} {very()} {well()}" #@@PLEAC@@_1.12 s.wrap(width) = ls, s' = s.words.foldl(([], ""), ((ls, s), word -> if "{s} {word}" > width then ls + [s], word else s' = (s &&& "{s} ") + word ls, s' )) join(ls + [s'], "\n") #@@PLEAC@@_1.14 s.subst!("^\s+", "") s.subst!("\s+$", "") s.trim = s.subst("^\s+", "").subst("\s+$", "") #@@PLEAC@@_2.5 print("Infancy is: ") ; 0..2.map(e -> print("{e} ")) print("Infancy is: ") ; 0..2.map(to_string).join(" ").print #@@PLEAC@@_2.7 rand = random(25 .. 75) # rand is in [25,75[ chars = "A".."Z" + "a".."z" + "0".."9" + q(!@$%^&*) password = 1..8.map(_ -> chars[random(chars.size)]).flatten #@@PLEAC@@_2.16 number = hex(hexadecimal) # hexadecimal number = to_int(octal, 8) # octal print("Gimme a number in decimal, octal, or hex: ") num = Sys::stdin.line.chomp num = num.pattern_matches( "^0x", hex(num), "^0", to_string(num, 8), "", num, ) "%d %x %o\n".printf(num, num, num) #@@PLEAC@@_2.17 s.commify = integer.fixpoint(subst(, "(\d)(\d\{3})($|\.|,)", (a,b,c -> "{a},{b}{c}"))) s.commify' = s.pattern_matches( "(.*)(...)", (a,b -> a.commify' + "," + b) "", s ) #@@PLEAC@@_4.1 a = ("quick", "brown", "fox") a = "Why are you teasing me?".words big_array = "mydatafile".open(Sep(crlf)).lines banner = "The Mines of Moria" banner = q(The Mines of Moria) name = "Gandalf" banner = "Speak, {name}, and enter!" banner = qq(Speak, {name}, and welcome!) ships = "Niña Pinta Santa María".words # WRONG ships = ("Niña", "Pinta", "Santa María") #@@PLEAC@@_4.2 commify_series = [] -> "" l -> l', e = l.pop l'.join(", ") + " and " + e array = ("red", "yellow", "green") println("I have {array.join(" ")} marbles.") #=> I have red yellow green marbles. #@@PLEAC@@_4.3 l.what_about_that_array = println("The array now has {l.size} elements.") println("The index of the last element is {l.size - 1}.") println("Element #3 is `{l[3]}'.") "Crosby Stills Nash Young".words.what_about_that_array #@@PLEAC@@_4.4 bad_users.each(complain) bad_users.each(user -> complain(user)) Sys::env.keys.sort.each(var -> "{var}={Sys::env{var}}".println) Sys::env.each(var, val -> "{var}={val}".println) # but non-sorted Sys::env.sort_by(a,_ , b,_ -> a <=> b).each(var, val -> "{var}={val}".println) bad_users.each(user -> if user.get_usage > Max_quota then complain(user) ) "who".popen.lines(s -> s.m!("tchrist", s.print) ) df.lines(s -> s.words.each(s -> s.rev.println) ) array.each(item -> "i = {item}".println) array.each(--) a = ( 0.5, 3 ); b = ( 0, 1 ) (a,b).each(l -> l.map(a -> a *= 7 "{a} ".print ) ) #@@PLEAC@@_4.6 unique = list.uniq # generate a list of users logged in, removing duplicates users = "who".popen.lines.map(m(,"(\S+)")).sort.uniq println("users logged in: {users}") #@@PLEAC@@_4.7 difference(a, b) #@@PLEAC@@_4.8 union(a, b) intersection(a, b) difference(union(a,b), intersection(a,b)) #@@PLEAC@@_4.9 members = ("Time", "Flies") initiates = ("An", "Arrow") members += initiates # members is now ("Time", "Flies", "An", "Arrow") members = ("Time", "Flies") initiates = ("An", "Arrow") members.insert!(2, "Like" + initiates) # members is now ("Time", "Flies", "Like", "An", "Arrow") members[0] = "Fruit" members[2,3] = "A", "Banana" # members is now ("Fruit", "Flies", "Like", "A", "Banana") #@@PLEAC@@_4.10 reversed = array.rev array.rev.each(e -> # do something with e () ) #@@PLEAC@@_4.11 a.shift2 = a.shift!, a.shift! a.pop2 = swap(a.pop!, a.pop!) friends = "Peter Paul Mary Jim Tim".words (this, that) = friends.shift2 # this contains Peter, that has Paul, and # friends has Mary, Jim, and Tim beverages = "Dew Jolt Cola Sprite Fresca".words pair = beverages.pop2 # pair[0] contains Sprite, pair[1] has Fresca, # and beverages has (Dew, Jolt, Cola) #@@PLEAC@@_4.12 highest_engineer = employees.find(employee -> employee.category == "engineer") println("Highest paid engineer is: {highest_engineer.name}") #@@PLEAC@@_4.13 bigs = nums.filter(n -> n > 1_000_000) pigs = users.filter(_, n -> n > 1e7).keys matching = popen("who").lines.filter(m(, "^gnat ")) engineers = employees.filter(employee -> employee.category == "engineer") secondary_assistance = applicants.filter(e -> e{Income} >= 26_000 && e{Income} < 30_000) #@@PLEAC@@_4.14 sorted = sort(non_sorted) # if non_sorted !> Vector(Int) # pids is an unsorted array of process IDs pids.sort.each(println) println("Select a process ID to kill:") try pid = Sys::stdin.line.chomp.to_int pid.kill(TERM) sleep(2) pid.kill(KILL) with Failed(To_int) -> die("Exiting ... \n") descending = non_sorted.sort_by(a,b -> b <=> a) #@@PLEAC@@_4.15 ordered = unordered.sort_by(compare) precomputed = unordered.map(e -> e.compute, e) ordered_precomputed = precomputed.sort_by(a,b -> a[0] <=> b[0]) ordered = ordered_precomputed.map(a -> a[0]) ordered = unordered.map(e -> e.compute, e) .sort_by(a,b -> a[0] <=> b[0]) .map(a -> a[0]) sorted = employees.sort_by(a,b -> a.name <=> b.name || b.age <=> a.age) # getpwent is an iterator users = getpwent().to_list users.sort_by!(a,b -> a{Name} <=> b{Name}) users.each(user -> user{Name}.println) sorted = names.sort_by(a,b -> a[1] <=> b[1]) sorted = string.sort_by(a,b -> a.size <=> b.size) sorted_fields = fields.map(e -> e.m("(\d+)"), e) .sort_by(a,b -> a[0] <=> b[0]) .map(a -> a[0]) "/etc/passwd".open .lmap(e -> e.split(":")[3,2,0], e) .sort_by(a,b -> a[1] <=> b[1] ||| # gid a[2] <=> b[2] ||| # uid a[3] <=> b[3] # login ) .map(a -> a[0]) #@@PLEAC@@_4.16 circular.unshift!(circular.pop!) # the last shall be first circular.push!(circular.shift!) # and vice versa l.grab_and_rotate = e = l.shift! l.push!(e) e processes = (1, 2, 3, 4, 5) loop process = grab_and_rotate(processes) println("Handling process {process}") sleep(1) #@@PLEAC@@_4.17 l.randomize! l.fisher_yates_shuffle = (l.size - 1 .. 0).each(i -> j = random(i+1) l[i,j] = l[j,i] if i != j ) l.naive_shuffle = l.each_with_index(_, i -> j = random(l.size) l[i,j] = l[j,i] if i != j ) #@@PLEAC@@_5.0 age = { "Nat" , 24, "Jules", 25, "Josh" , 17, } age{"Nat"} = 24 age{"Jules"} = 25 age{"Josh"} = 17 #@@PLEAC@@_5.1 food_color = { "Apple" , "red", "Banana", "yellow", "Lemon" , "yellow", "Carrot", "orange", } food_color{"Raspberry"} = "pink" println("Known foods:") food_color.keys.each(println) #@@PLEAC@@_5.2 ("Banana", "Martini").each(name -> println("{name} is a {if food_color.key?(name) then "food" else "drink"}") ) # Banana is a food. # Martini is a drink. #@@PLEAC@@_5.3 food_color.remove_key!("Banana") #@@PLEAC@@_5.4 food_color.each(food, color -> "{food} is {color}.".println) food_color.keys.sort.each(food -> "{food} is {food_color{food}}.".println) #@@PLEAC@@_5.5 hash.each(k,v -> "{k} => {v}".println) #@@PLEAC@@_5.6 # the default should be to keep the order, so no pb here. #@@PLEAC@@_5.7 ttys = {} popen("who").each(s -> user, tty = s.words[0,1] #ttys{user} = [] if not ttys.key?(user) <- not needed, auto created with *** ttys{user}.push!(tty) ) ttys.keys.sort.each(user -> "{user}: {ttys{user}.join(", ")}".println) # or the more functional: popen("who").foldl({}, (ttys, s -> user, tty = s.words[0,1] #ttys{user} = [] if not ttys.key?(user) <- not needed, auto created with *** ttys{user}.push(tty) )).keys.sort.each(user -> "{user}: {ttys{user}.join(", ")}".println) #@@PLEAC@@_5.8 surname = { "Mickey","Mantle" , "Babe","Ruth" } println(surname.value2key("Mantle")) # => Mickey #@@PLEAC@@_5.9 food_color.keys.sort.each(food -> "{food} is {food_color{food}}.".println) #@@PLEAC@@_5.10 merged = a + b drink_color = { "Galliano","yellow" , "Mai Tai","blue" } ingested_colors = drink_color + food_color substance_color = drink_color + food_color intersection(drink_color, food_color).each(k,_ -> println("Warning: {k} seen twice. Using the last definition.") ) #@@PLEAC@@_5.11 all_colors += new_colors common = intersection(hash1, hash2).keys common = intersection(hash1.keys, hash2.keys) citrus_color = { "Lemon", "yellow", "Orange", "orange", "Lime", "green", } non_citrus = difference(food_color, citrus_color).keys non_citrus = difference(food_color.keys, citrus_color.keys) #@@PLEAC@@_5.12 # no pb, merd's dicts handle any kind of objects which have Eq #@@PLEAC@@_5.13 # TODO #@@PLEAC@@_5.14 count = {} array.each(e -> count{e}++) #@@PLEAC@@_5.15 father = { "Cain" , "Adam", "Abel" , "Adam", "Seth" , "Adam", "Enoch" , "Cain", "Irad" , "Enoch", "Mehujael" , "Irad", "Methusael" , "Mehujael", "Lamech" , "Methusael", "Jabal" , "Lamech", "Jubal" , "Lamech", "Tubalcain" , "Lamech", "Enos" , "Seth", } Sys::stdall.each(e -> e.chomp! #fathers = e : e.unfoldr1(e -> Some(father{e}) or None) #println(fathers.join(" ")) print("{e}") try loop e = fathers{e} print("{e} ") with _ -> println("") ) Sys::stdall.each(e -> e.chomp! children = father.key2values(e) ||| [ "nobody" ] println("{e} begat {children.join(", ")}.") ) includes = {} files.each(file -> try file.open.each(s -> s.pattern_matches( "^\s*#\s+include\s+<(.*?)>", f -> includes.push!(f) ) ) with File_error(err) -> warn("Couldn't read {file}: {err}; skipping.\n") ) include_free = # list of files that don't include others difference(includes.values.flatten.uniq, includes.keys) #@@PLEAC@@_6.0 meadow.m!(I, "\bovines?\b", println("Here be sheep!")) string = "good food" string.subst!("o*", "e") "ababacaca".m!( "((a|ba|b)+(a|ac)+)", s,_,_ -> s.println ) # => ababa s.m!(G, "(\d+)", e->println("Found number {e}")) numbers = s.m(G, "(\d+)") #@@PLEAC@@_6.1 dst = src.subst("this", "that") # Make All Words Title-Cased capword = word.subst(G, "(\w+)", capitalize) # /usr/man/man3/foo.1 changes to /usr/man/cat3/foo.1 catpage = manpage.subst("man(?=\d)", "cat") bindirs = " /usr/bin /bin /usr/local/bin ".words libdirs = bindirs.map(subst(, "bin", "lib")) println(libdirs.join(" ")) # /usr/lib /lib /usr/local/lib #@@PLEAC@@_6.5 s = "One fish two fish red fish blue fish" want = 3 count = 0 s.m!( G|I, "(\w+)\s+fish\b", s -> count++ if count == want then println("The third fish is a {s} one.") # => red ) s.m!( I, "(?:\w+\s+fish\s+)\{2}(\w+)\s+fish", s -> println("The third fish is a {s} one.") # => red ) colors = s.m(G|I, "(\w+)\s+fish\b") println("The third fish is a {colors[2]} one.") # => red pond = "One fish two fish red fish blue fish swim here." color = pond.m(G|I, "\b(\w+)\s+fish\b").last println("Last fish is {color}.") #=> Last fish is blue. #@@PLEAC@@_6.8 file.open.to_list.each_with_index(s,i -> println(s) if i.member?(15 .. 17)) r = Regexp::new_range(m?(, I, "